iOS UITextView putting character onto next line - ios

In this picture with a UITextView saying "Coordinate Geometry", the "e" gets put onto the next line. There is no line space there. I have also tried this with a UILabel (I switched to UITextView to try and fix the problem but there was no difference).
Here is my code for my subclass of UITextView
- (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text circular:(BOOL)isCircular {
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor lightGrayColor];//[UIColor clearColor];
self.alpha = 0.5;
self.textColor = [Styles mainTextColour];
[self setFont:[Styles heading2Font]];
[self setTextAlignment:NSTextAlignmentCenter];
self.text = text;
self.editable = NO;
self.contentInset = UIEdgeInsetsMake(-8, 0, -8, 0);
[self resizeFontToFix];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame {
NSAssert(NO, #"Don't use BubbleText -initWithFrame:, use -initWithFrame: andText: instead");
return nil;
}
- (void)resizeFontToFix {
//Resize to fix
CGFloat fontSize = self.font.pointSize;
CGFloat minSize = 6.0 * [Styles sizeModifier];
while (fontSize > minSize && [self sizeThatFits:(CGSizeMake(self.frame.size.width, FLT_MAX))].height >= self.frame.size.height) {
fontSize -= 1.0;
self.font = [self.font fontWithSize:fontSize];
}
//this below resizes to fit and centres the resulting view
// [self resizeFrameAndCentre];
}
- (void)resizeFrameAndCentre {
CGRect originalFrame = self.frame;
[self sizeToFit];
CGPoint centre = self.center;
centre.x = originalFrame.origin.x + (originalFrame.size.width / 2);
centre.y = originalFrame.origin.y + (originalFrame.size.height / 2);
self.center = centre;
}

Related

__block modifier creates unreadable memory

Now Im developing a banner showing feature in iOS
It's a singleton which shows banner on the upper part of screen when user logs in.
It's basically a shared view with a class method showWithName...
#interface XXUserWelcomeBanner ()
{
UIImageView *logoView;
UILabel *textLabel;
CGFloat _width;
}
#end
When user calls, it creates a UIImageView and a UILabel to add on self. And animates itself onto the screen.
+ (XXUserWelcomeBanner *)shared {
static dispatch_once_t onceToken;
static XXUserWelcomeBanner *userWelcomBanner;
dispatch_once(&onceToken, ^{
userWelcomBanner = [[XXUserWelcomeBanner alloc] init];
});
return userWelcomBanner;
}
+ (void)showWithUserName:(NSString *)userID andLogo:(UIImage * _Nullable)logo {
dispatch_async(dispatch_get_main_queue(), ^{
[[self shared] createWithName:userID andLogo:logo];
});
}
So there's this other bug I just found that causes this method to be called twice and on the second time it shows only the UIImageView.
And I don't understand why that's happening.
Because the UIImageView and UILabel won't be created twice.
Here's more code.
#pragma mark - private
- (void)createWithName:(NSString *)name andLogo:(UIImage * _Nullable)logo {
self.opaque = NO;
self.alpha = 0.9;
self.backgroundColor = COLOR(0xfcfcfc);
// if (#available(iOS 13.0, *)) {
// self.backgroundColor = UIColor.secondarySystemBackgroundColor;
// }
CGSize labelSize = CGSizeZero;
if (logoView == nil) {
if (logo != nil) {
logoView = [[UIImageView alloc] initWithImage:logo];
[self addSubview:logoView];
} else {
NSString *imagePath = [XXUtility pathForResourceNamed:#"Logo" withExtension:#"png"];
UIImage *imageToAdd = [[UIImage alloc] initWithContentsOfFile:imagePath];
logoView = [[UIImageView alloc] initWithImage:imageToAdd];
[self addSubview:logoView];
}
}
if (textLabel == nil) {
textLabel = [[UILabel alloc] init];
NSString * labelString = [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(#"welcom banner", #"userInterface", [XXUtility bundleForStrings], #"Dear %#, welcome into game", #"user welcome banner text"), name];
labelSize = [labelString sizeWithAttributes:#{NSFontAttributeName : textLabel.font}];
textLabel.text = labelString;
[self addSubview:textLabel];
}
NSLog(#"XXUserWelcomeBanner Label size is %f x %f", labelSize.height, labelSize.width);
[self bannerSizeWithLabelSize:labelSize];
CGFloat bannerHeight = self.frame.size.height;
CGFloat bannerWidth = self.frame.size.width;
CGFloat logoHeight = bannerHeight * 0.45;
CGFloat logoWidth = logoHeight;
CGFloat logoXPos = (bannerWidth - logoWidth - labelSize.width) / 2;
CGFloat logoYPos = (bannerHeight - logoHeight) / 2;
CGFloat labelHeight = labelSize.height;
CGFloat labelWidth = labelSize.width;
CGFloat labelXPos = logoXPos + logoWidth + 5;
CGFloat labelYPos = (bannerHeight - labelHeight) / 2;
logoView.frame = CGRectMake(logoXPos, logoYPos, logoWidth, logoHeight);
textLabel.frame = CGRectMake(labelXPos, labelYPos, labelWidth, labelHeight);
[self bannerShow];
}
- (void)bannerSizeWithLabelSize:(CGSize)lSize {
_width = 40 + lSize.width + 5;
CGFloat height = 40;
CGFloat xPosition = ScreenWidth * 1/2 - _width * 1/2;
CGFloat yPosition = - height;
self.frame = CGRectMake(xPosition, yPosition, _width, height);
}
- (void)bannerShow {
UIViewController *vc;
if ([TOP_VIEWCONTROLLER respondsToSelector:#selector(topViewController)]) {
vc = [TOP_VIEWCONTROLLER topViewController];
} else {
vc = TOP_VIEWCONTROLLER;
}
[vc.view addSubview:self];
[UIView animateWithDuration:0.6 delay:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^{
CGFloat height = 40;
CGFloat xPos = ScreenWidth * 1/2 - self->_width * 1/2;
CGFloat yPos = height * 1/3 + KiPhoneXSafeAreaDValue;
self.frame = CGRectMake(xPos, yPos, self->_width, height);
} completion:^(BOOL finished) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.6 delay:0.2 options:UIViewAnimationOptionCurveEaseIn animations:^{
CGFloat height = 40;
CGFloat xPosition = ScreenWidth * 1/2 - self->_width * 1/2;
CGFloat yPosition = - height;
self.frame = CGRectMake(xPosition, yPosition, self->_width, height);
} completion:^(BOOL finished) {
[self bannerDestroy];
self.alpha = 0;
}];
});
}];
}
- (void)bannerDestroy {
[logoView removeFromSuperview];
[textLabel removeFromSuperview];
logoView = nil;
textLabel = nil;
[self removeFromSuperview];
}
- (void)dealloc
{
//
NSLog(#"uiview dealloc");
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
#end
Thanks in advance.
It is expected that createWithName:andLogo: is calling more than once in your app. I guess you call it with different arguments, that's why it should not be inside dispatch_once(&onceToken, ^{ });. But you can optimise XXUserWelcomeBanner's init:
- (instancetype)init {
self = [super init];
if (self) {
logoView = [[UIImageView alloc] init];
[self addSubview:logoView];
textLabel = [[UILabel alloc] init];
[self addSubview:textLabel];
}
return self;
}
In createWithName:andLogo: you will have the following:
if (logo != nil) {
logoView.image = logo;
} else {
NSString *imagePath = [XXUtility pathForResourceNamed:#"Logo" withExtension:#"png"];
UIImage *imageToAdd = [[UIImage alloc] initWithContentsOfFile:imagePath];
logoView.image = imageToAdd;
}
NSString * labelString = [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(#"welcom banner", #"userInterface", [XXUtility bundleForStrings], #"Dear %#, welcome into game", #"user welcome banner text"), name];
CGSize labelSize = [labelString sizeWithAttributes:#{NSFontAttributeName : textLabel.font}];
textLabel.text = labelString;

UILabel auto scroll like a marquee

I am trying I make a UI label auto scroll the text that is inside it like a marquee. The below code works depending on what kind of text/content I throw at it. I can't tell what works and what does not. What happens is that the label does not show anything, then suddenly scrolls the text at an extremely high speed that you can't read it.
For some reason, this works perfectly on the iPhone but not on the iPad. I am guessing because the text I am putting at the iPhone is always way bigger than the Uilabel's size?
Here is the code:
self.currentTrack.textColor = [UIColor colorWithRed:15.0/255.0 green:176.0/255.0 blue:223.0/255.0 alpha:1];
self.currentTrack.labelSpacing = 35; // distance between start and end labels
self.currentTrack.pauseInterval = 1.7; // seconds of pause before scrolling starts again
self.currentTrack.scrollSpeed = 30; // pixels per second
self.currentTrack.textAlignment = NSTextAlignmentCenter; // centers text when no auto-scrolling is applied
self.currentTrack.fadeLength = 12.f;
self.currentTrack.scrollDirection = CBAutoScrollDirectionLeft;
[self.currentTrack observeApplicationNotifications];
}
Here is the code:
AutoScrollLabel, extended from UIView (code provided below) has an instance method to set text (setLabelText). The text provided will auto scroll only if the length of the text is bigger than the width of the AutoScrollLabel view.
Eg:
AutoScrollLabel *autoScrollLabel = [[AutoScrollLabel alloc] initWithFrame:CGRectMake(0, 0, 150, 25)];
[autoScrollLabel setLabelText:#"Some lengthy text to be scrolled"];
Note: You can make changes in setLabelText: Method implementation to support Attributed Text (use appropriate methods to find size of Attributed Text)
*** AutoScrollLabel.h
#interface AutoScrollLabel : UIView {
UILabel *textLabel;
NSTimer *timer;
}
- (void) setLabelText:(NSString*) text;
- (void) setLabelFont:(UIFont*)font;
- (void) setLabelTextColor:(UIColor*)color;
- (void) setLabelTextAlignment:(UITextAlignment)alignment;
#end
**** AutoScrollLabel.m
#import "AutoScrollLabel.h"
#import <QuartzCore/QuartzCore.h>
#implementation AutoScrollLabel
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
self.clipsToBounds = YES;
self.autoresizesSubviews = YES;
textLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
textLabel.backgroundColor = [UIColor clearColor];
textLabel.textColor = [UIColor blackColor];
textLabel.textAlignment = UITextAlignmentRight;
[self addSubview:textLabel];
}
return self;
}
-(void) setLabelText:(NSString*) text {
textLabel.text = text;
CGSize textSize = [text sizeWithFont:textLabel.font];
if(textSize.width > self.frame.size.width) {
textLabel.frame = CGRectMake(0, 0, textSize.width, self.frame.size.height);
}
else {
textLabel.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}
if(textLabel.frame.size.width > self.frame.size.width) {
[timer invalidate];
timer = nil;
CGRect frame = textLabel.frame;
frame.origin.x = self.frame.size.width-50;
textLabel.frame = frame;
timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(moveText) userInfo:nil repeats:YES];
}
else {
[timer invalidate];
timer = nil;
}
}
-(void) moveText {
if(textLabel.frame.origin.x < textLabel.frame.size.width-2*textLabel.frame.size.width) {
CGRect frame = textLabel.frame;
frame.origin.x = self.frame.size.width;
textLabel.frame = frame;
}
[UIView beginAnimations:nil context:nil];
CGRect frame = textLabel.frame;
frame.origin.x -= 5;
textLabel.frame = frame;
[UIView commitAnimations];
}
- (void) setLabelFont:(UIFont*)font {
textLabel.font = font;
}
- (void) setLabelTextColor:(UIColor*)color {
textLabel.textColor = color;
}
- (void) setLabelTextAlignment:(UITextAlignment)alignment {
textLabel.textAlignment = alignment;
}
For Swift5
set top of your UILabel equal to superview bottom, and then use this code:
func createAnimationLbl() -> CAAnimation {
let animation = CABasicAnimation(keyPath: "transform.translation.y")
animation.fromValue = 0
animation.toValue = -(self.view.frame.height )
animation.duration = 15
animation.repeatCount = Float.infinity //times of scrolling, infinity for unlimited times.
animation.timingFunction = CAMediaTimingFunction.init(name: CAMediaTimingFunctionName.linear)
animation.fillMode = CAMediaTimingFillMode.forwards
animation.isRemovedOnCompletion = false
return animation
}
then in your viewWillAppear call it as below:
self.aboutLbl.layer.add(createAnimationLbl(), forKey: nil)

IOS RoundView make child ImageView to be rounded

I've created this custom UIView named RoundView:
#import <QuartzCore/QuartzCore.h>
#implementation RoundedView
+(UIColor *)grayUIColor {
return [UIColor colorWithRed:161.0/255.0 green:157.0/255.0 blue:164.0/255.0 alpha:1.0];
}
+(UIColor *)darkBlueUIColor {
return [UIColor colorWithRed:86.0/255.0 green:88.0/255.0 blue:87.0/255.0 alpha:1];
}
+(UIColor *)greenUIColor {
return [UIColor colorWithRed:51.0/255.0 green:141.0/255.0 blue:130.0/255.0 alpha:1];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self)
{
//add pico icon as default image
_defaultImage = [UIImage imageNamed:#"actionBar_pico_icon"];
_isCreated = NO;
}
return self;
}
-(UIView*)createRoundViewWithBorder:(UIColor*)borderColor andPaddingColor:(UIColor*)paddingColor{
_borderColor = borderColor;
_paddingBackgroundColor = paddingColor;
[self setViewAppearance];
[self addImageToView];
_isCreated = YES;
return self;
}
/**
Set the current view appearance
*/
-(void) setViewAppearance {
self.layer.borderWidth = 1.5;
self.layer.borderColor = [_borderColor CGColor];
self.backgroundColor = _paddingBackgroundColor;
}
-(void) addImageToView {
CGRect frame = CGRectMake(0, 0, self.frame.size.width - 5, self.frame.size.height - 5);
_imageView = [[UIImageView alloc] initWithFrame:frame];
//calculate center x
float x = (self.frame.size.width - _imageView.frame.size.width) / 2;
//calculate center y
float y = (self.frame.size.height - _imageView.frame.size.height) / 2;
//create new frame
frame = CGRectMake(x, y, _imageView.frame.size.width, _imageView.frame.size.height);
_imageView.image = _defaultImage;
_imageView.frame = frame;
_imageView.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:_imageView];
[self makeViewRounded:_imageView];
[self makeViewRounded:self];
}
-(UIView*) makeViewRounded:(UIView*)view {
//set the look of the image
view.layer.cornerRadius= self.frame.size.height /2;
view.layer.opaque = NO;
view.layer.masksToBounds = YES;
return view;
}
-(void)updateImage:(UIImage *)image {
_image = image;
_imageView.image = image;
}
-(void)reset {
[self updateImage:_defaultImage];
}
#end
an example for the output will be :
If you look closely you will notice that the border is a circle, but the image view has edges.
How can i make the Image smooth as well ?
self.imgViewbg.layer.cornerRadius = self.imgViewbg.frame.size.width / 2;
self.imgViewbg.clipsToBounds = YES;
u Can Try This Code. And Implement in your Project..
It Will Definetly Work.. for u
I think the problem seems to be here:
view.layer.cornerRadius= self.frame.size.height /2;
Try giving it a constant small number and see the change. May be the height/2 is not making a perfect circle. You can give a smaller value than height/2 and see the change. It a wild guess by watching your image.

Zooming UIImageView in a UIScrollView acts weirdly

I have the following problem, guys. I have an app that is pretty much like Apple's PhotoScroller. I want to jump from image to image by swiping the screen. I can do that, but I can't zoom the images. Here's the problem - I have an array with images. If the array has only one object inside, there's no problem with zooming. But if there are more images in the array, they acts weirdly when I try to zoom. The image is not being zoomed and it goes where it wants off the screen. Here is my code:
int pageWidth = 1024;
int pageHeight = 768;
int counter = 0;
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, pageWidth, pageHeight)];
CGRect containerFrame = self.view.frame;
scrollView = [[UIScrollView alloc] initWithFrame:containerFrame];
[self.view addSubview:scrollView];
NSMutableArray *all = [[NSMutableArray alloc] init];
[all addObject:[UIImage imageNamed:#"222.jpg"]];
CGSize scrollSize = CGSizeMake(pageWidth * [all count], pageHeight);
[scrollView setContentSize:scrollSize];
for (UIImage *image in all)
{
UIImage *pageImage = [[UIImage alloc] init];
pageImage = [all objectAtIndex:counter];
CGRect scrollFrame = CGRectMake(pageWidth * counter, 0, pageWidth, pageHeight);
miniScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
[scrollView addSubview:miniScrollView];
CGSize miniScrollSize = CGSizeMake(pageImage.size.width, pageImage.size.height);
[miniScrollView setContentSize:miniScrollSize];
UIImageView *tempImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, pageImage.size.width, pageImage.size.height)];
tempImageView.image = [all objectAtIndex:counter];
self.imageView = tempImageView;
miniScrollView.maximumZoomScale = 3.0;
miniScrollView.minimumZoomScale = 1.0;
miniScrollView.clipsToBounds = YES;
miniScrollView.delegate = self;
miniScrollView.showsHorizontalScrollIndicator = NO;
miniScrollView.showsVerticalScrollIndicator = NO;
miniScrollView.bouncesZoom = YES;
[miniScrollView addSubview:imageView];
counter ++;
}
[scrollView setPagingEnabled:YES];
[scrollView setScrollEnabled:YES];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
Do you have any ideas what's wrong? Because I am trying to get this work almost 2 weeks.
I also worked on such sort of App. The first thing that you can do is to take a separate subclass of your ScrollView so that all the paging and zooming operations can be handled easily. In your scrollView Class, You can take reference from the following code snippet.
#interface PhotoScrollView : UIScrollView<UIScrollViewDelegate,UIGestureRecognizerDelegate>
{
int finalPhotoWidth;
int finalPhotoHeight;
}
// to contain image
#property (strong, nonatomic) UIImageView *imageView;
- (id)initWithFrame:(CGRect)frame andImage:(UIImage *)photo
{
self = [super initWithFrame:frame];
if (self)
{
// Initialization code
[self initializeScrollViewWithImage:photo];
//setting gesture recognizer for single tap
UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewSingleTapped:)];
singleTapRecognizer.delegate = self;
singleTapRecognizer.numberOfTapsRequired = 1;
[self addGestureRecognizer:singleTapRecognizer];
//setting gesture recognizer for Double tap
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(scrollViewDoubleTapped:)];
doubleTapRecognizer.delegate = self;
doubleTapRecognizer.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleTapRecognizer];
[singleTapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
singleTapActivated = FALSE;
self.backgroundColor = [UIColor blackColor];
self.minimumZoomScale = 1.0f;
self.maximumZoomScale = 15.0f;
self.zoomScale = 1.0f;
self.delegate = self;
}
return self;
}
//for sizing the frame by giving height and width
-(void)initializeScrollViewWithImage:(UIImage*)photo
{
finalPhotoWidth = photo.size.width;
finalPhotoHeight = photo.size.height;
//Pre-checking of frame and setting the height and width accordingly
if (finalPhotoHeight > self.frame.size.height)
{
// if photo height is bigger than frame height, re-adjust the photo height and width accordingly
finalPhotoHeight = self.frame.size.height;
finalPhotoWidth = (photo.size.width/photo.size.height) * finalPhotoHeight;
}
if (finalPhotoWidth > self.frame.size.width)
{
// if photo width is bigger than frame width, re-adjust the photo height and width accordingly
finalPhotoWidth = self.frame.size.width;
finalPhotoHeight = (photo.size.height/photo.size.width) * finalPhotoWidth;
}
if (finalPhotoHeight < self.frame.size.height && finalPhotoWidth < self.frame.size.width)
{
// if the photo is smaller than frame, increase the photo width and height accordingly
finalPhotoWidth = self.frame.size.width;
finalPhotoHeight = self.frame.size.height;
}
//initialising imageView with the thumbnail photo
self.imageView = [[UIImageView alloc] initWithImage:photo];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
//setting frame according to the modified width and height
if(!isnan(finalPhotoWidth) && !isnan(finalPhotoHeight))
{
self.imageView.frame = CGRectMake( (self.frame.size.width - finalPhotoWidth) / 2, (self.frame.size.height - finalPhotoHeight)/2, finalPhotoWidth, finalPhotoHeight);
}
// setting scrollView properties
self.contentSize = self.imageView.frame.size;
// add image view to scroll view
[self addSubview:self.imageView];
}
//to deny the simultaneous working of single and double taps
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return NO;
}
// Gesture handleer for single tap gesture
-(void)scrollViewSingleTapped:(UITapGestureRecognizer *)recognizer
{
if(!singleTapActivated)
{
//do as per requirement
singleTapActivated = TRUE;
}
else
{
//do as per requirement
singleTapActivated = FALSE;
}
}
//for zooming after double tapping
- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
{
//to check whether image is zoomed
if (self.zoomScale != 1.0f)
{
//if image is zoomed, then zoom out
[self setZoomScale:1.0 animated:YES];
self.imageView.frame = CGRectMake( (self.frame.size.width - finalPhotoWidth) / 2, (self.frame.size.height - finalPhotoHeight)/2, finalPhotoWidth, finalPhotoHeight);
[self.observer photoZoomStopped];
}
else
{
// get the point of image which is double tapped
CGPoint pointInView = [recognizer locationInView:self.imageView];
// Get a zoom scale that's zoomed in slightly, capped at the maximum zoom scale specified by the scroll view
CGFloat newZoomScale = self.zoomScale * 4.0f;
newZoomScale = MIN(newZoomScale, self.maximumZoomScale);
// Figure out the rect we want to zoom to, then zoom to it
CGSize scrollViewSize = self.imageView.frame.size;
CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = pointInView.x - (w / 2.0f);
CGFloat y = pointInView.y - (h / 2.0f);
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
[self zoomToRect:rectToZoomTo animated:YES];
}
}
// To re-center the image after zooming in and zooming out
- (void)centerScrollViewContents
{
CGSize boundsSize = self.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width)
{
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
}
else
{
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height)
{
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
}
else
{
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
//for zooming in and zooming out
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
if (self.zoomScale > 1.0f)
{
[self.observer photoZoomStarted];
[self centerScrollViewContents];
}
else
{
self.bouncesZoom = NO;
[self.observer photoZoomStopped];
// for zooming out by pinching
[self centerScrollViewContents];
}
// The scroll view has zoomed, so we need to re-center the contents
}
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
Please let me know if it helps. Thanks :)

Multiline UILabel with padding in autolayout, in UITableView

I have a UILabel in a UITableView that should be a maximum of 2 lines and have a bit of padding around it (7 left and right and 2 top and bottom). I'm using autolayout and targeting only iOS6 and above. All views are being created and added programatically.
I've subclassed my UILabel, here's the init method:
- (id)init
{
self = [super init];
self.translatesAutoresizingMaskIntoConstraints = NO;
self.numberOfLines = 2;
self.backgroundColor = UIColorFromARGB(0x99000000);
self.textColor = [UIColor whiteColor];
self.font = [UIFont boldSystemFontOfSize:14.0f];
return self;
}
If I add this in, I get the right padding, but it makes it just one line:
- (void)drawTextInRect:(CGRect)rect {
UIEdgeInsets insets = {2, 7, 2, 7};
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, insets)];
}
I've seen this answer a few times, but it doesn't work for me (no effect):
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines
{
UIEdgeInsets insets = {2, 7, 2, 7};
return [super textRectForBounds:UIEdgeInsetsInsetRect(bounds,insets) limitedToNumberOfLines:numberOfLines];
}
Does it make a difference that its in a table view? Any help would be appreciated.
As you saw in my above comment, you didn't really say what it's doing that you don't expect. I've just done this myself, and this works with autolayout:
#implementation InsetLabel
- (void) setInsets:(UIEdgeInsets)insets
{
_insets = insets ;
[self invalidateIntrinsicContentSize] ;
}
- (void)drawTextInRect:(CGRect)rect
{
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)];
}
- (void)resizeHeightToFitText
{
CGRect frame = [self bounds];
CGFloat textWidth = frame.size.width - (self.insets.left + self.insets.right);
CGSize newSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(textWidth, 1000000) lineBreakMode:self.lineBreakMode];
frame.size.height = newSize.height + self.insets.top + self.insets.bottom;
self.frame = frame;
}
- (CGSize) intrinsicContentSize
{
CGSize superSize = [super intrinsicContentSize] ;
superSize.height += self.insets.top + self.insets.bottom ;
superSize.width += self.insets.left + self.insets.right ;
return superSize ;
}
#end
#implementation InsetLabel
- (void) setInsets:(UIEdgeInsets)insets
{
_insets = insets ;
[self invalidateIntrinsicContentSize] ;
}
- (void)drawTextInRect:(CGRect)rect
{
return [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.insets)];
}
- (void)resizeHeightToFitText
{
CGRect frame = [self frame];
CGFloat textWidth = frame.size.width - (self.insets.left + self.insets.right);
CGSize newSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(textWidth, 1000000) lineBreakMode:self.lineBreakMode];
frame.size.height = newSize.height + self.insets.top + self.insets.bottom;
self.frame = frame;
}
- (CGSize) intrinsicContentSize
{
CGSize superSize = [super intrinsicContentSize] ;
superSize.height += self.insets.top + self.insets.bottom ;
superSize.width += self.insets.left + self.insets.right ;
return superSize ;
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self resizeHeightToFitText];
}
This works even better imho.

Resources