Hardcoded UIView vs. XIB UIView resizing - ios

I'm stumbled on how to layout a UITextField when there is a hardcoded UIImageView. UIImageView is hardcoded, let me show it:
// Image
CGFloat xCenter = self.view.frame.size.width / 2.00;
CGFloat yCenter = self.view.frame.size.height / 2.00;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
self.imageFrame = CGRectMake(xCenter + 115, yCenter - 425, 250, 250);
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
self.imageFrame = CGRectMake(xCenter - 125 , yCenter, 250, 250);
}
if ([[BNRImageStore sharedStore] imageForKey:self.item.itemKey]) {
self.imageView = [[UIImageView alloc] initWithFrame:self.imageFrame];
self.imageView.image = [[BNRImageStore sharedStore] imageForKey:self.item.itemKey];
[self.imageView.layer setBorderColor:(__bridge CGColorRef)([UIColor blackColor])];
[self.imageView.layer setBorderWidth:3.0];
self.imageView.contentMode = UIViewContentModeScaleAspectFill;
self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.imageView];
NSDictionary *nameMap =#{#"imageView": self.imageView,
#"nameLabel": self.nameLabel,
#"nameField": self.nameField};
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-[nameLabel]-[nameField]-[imageView(==250)]-|" options:0 metrics:nil views:nameMap];
[self.view addConstraints:#[horizontalConstraints]];
}
else {
UIView *imageCanvasView = [[UIView alloc] initWithFrame:self.imageFrame];
imageCanvasView.backgroundColor = [UIColor colorWithWhite:1.00 alpha:0.4];
imageCanvasView.layer.borderWidth = 1.0f;
imageCanvasView.layer.borderColor = [UIColor colorWithWhite:0.00 alpha:0.9].CGColor;
[self.view addSubview:imageCanvasView];
UILabel *addImageLabel = [[UILabel alloc] initWithFrame:self.imageFrame];
addImageLabel.text = #"(tap to add image)";
addImageLabel.font = [UIFont fontWithName:#"AvenirNext-UltraLight"
size:20];
addImageLabel.textColor = [UIColor WHITE_COLOR_DEBUG_FIX];
addImageLabel.textAlignment = NSTextAlignmentCenter;
addImageLabel.hidden = NO;
[self.view addSubview:addImageLabel];
}
Seems it's what I need:
But not in iPad:
Except UIImageView *imageView property, I made the constants with Auto Layout. Since XIB file doesn't recognize imageView I couldn't set the constraints of it. Instead I can use VFL, but constraints intersect at some point. Thus I couldn't managed it out.
Any ideas? (or is it possible in some way?)

I had a similar problem, I resolved it by creating two holder UIViews either on storyboard or programmatically - one holding the form and one holding the hardcoded UIImageView.
If you're using storyboards : Set the constraints on those two holding views and in the subviews of the one containing the form. And just place your UIImageView programmatically in the center of your image-holding view.

Related

Adding an Image with a Title in a UINavigationController

I would like to show a small icon next to the title in my UINavigationController.
Through the magic of Photoshop, like this:
I know I need to create a new view and build the image and title into it. Here is what I am doing:
In viewDidLoad in the UINavigationController view controller, I call the method
[self setTitleBar];
Which calls this method:
- (void) setTitleBar {
CGRect navBarFrame = self.navigationController.navigationBar.frame;
//UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(navBarFrame.origin.x, navBarFrame.origin.y, (leftButtonFrame.origin.x + leftButtonFrame.size.width) - rightButtonFrame.origin.x, navBarFrame.size.height)];
UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(navBarFrame.origin.x, navBarFrame.origin.y,self.view.frame.size.width,navBarFrame.size.height)];
titleView.backgroundColor = [UIColor clearColor];
CGPoint tvCenter = CGPointMake(titleView.frame.size.width/2, titleView.frame.size.height/2);
UIImage * icon = [UIImage imageNamed:#"star"];
UIImageView *iconView = [[UIImageView alloc] initWithImage:icon];
iconView.frame = CGRectMake(0, 0, icon.size.width, icon.size.height);
UILabel *title = [[UILabel alloc] init];
title.backgroundColor = [UIColor clearColor];
title.textColor = [UIColor whiteColor];
title.textAlignment = NSTextAlignmentCenter;
title.text = #"SOME TITLE";
title.frame = CGRectMake(0, 0, 100, titleView.frame.size.height);
[title sizeToFit];
iconView.center = CGPointMake(tvCenter.x - (icon.size.width/2), tvCenter.y);
[titleView addSubview:iconView];
[titleView addSubview:title];
self.navigationItem.titleView = titleView;
}
My logic in the titleView is: Get the left most button's frame and get the right most buttons frame. THEN do some math to figure out how big the view can be. That should be the titleView's frame size.
However, I can't seem to get it to work. If I plug in a frame size of 0,0,100,40; then it shows the frame but everything is squished together. But you see it. I know that 100 should be dynamic to ensure that the title is shown.
But I can't seem to figure it out.
Any help?
You can place objects on the Navigation Controller View, as subviews.
- (void) setTitleBar {
//Let's say your icon size is 20
int starSize = 20;
//Now you'll have to calculate where to place the ImageView respect the TextSize (for this you'll need to know the text and font of your UINavigationItem title)
CGSize textSize = [#"SOME TITLE" sizeWithAttributes:#{NSFontAttributeName:[UIFont fontWithName:#"navfontname" size:15]}];
UIImageView *startImageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.navigationController.view.frame.size.width/2 - textSize.width/2, self.navigationController.view.frame.size.height/2 - starSize/2, starSize,starSize)];
startImageView.image = [UIImage imageNamed:#"star"];
[self.navigationController.view addSubview:startImageView];
}

scrollView with paging enabled not working properly ? (Objective-C)

i want to create paging scrollView with three UIViews. And than wants to add imageView as a subView to these UIViews. i cant figure it out how to calculate the frame of imageViews.
When i run the code without imageViews it works perfectly fine.
- (void)viewDidLoad
{
[super viewDidLoad];
self.scrollView.delegate = self;
self.scrollView.frame = self.view.frame;
NSArray *colorsArray = [NSArray arrayWithObjects:[UIColor blueColor], [UIColor yellowColor],[UIColor greenColor], nil];
NSArray *imagesArray = [NSArray arrayWithObjects:[UIImage imageNamed:#"123.png"],[UIImage imageNamed:#"13.png"],[UIImage imageNamed:#"12.png"],nil];
for (int i = 0; i < colorsArray.count; i++) {
CGRect frame;
frame.origin.x = self.view.frame.size.width * i;
frame.size = self.view.frame.size;
self.scrollView.pagingEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:frame];
view.backgroundColor = [colorsArray objectAtIndex:i];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:view.frame];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image = [imagesArray objectAtIndex:i];
[view addSubview:imageView];
[self.scrollView addSubview:view];
}
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width * colorsArray.count, self.scrollView.frame.size.height);
self.pageControl.numberOfPages = 3;
self.pageControl.currentPage = 0;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat pageWidth = CGRectGetWidth(self.scrollView.bounds);
CGFloat pageFraction = self.scrollView.contentOffset.x / pageWidth;
self.pageControl.currentPage = roundf(pageFraction);
}
The frame for the image view needs to be relative to its superview (i.e. view) not the scroll view. To achieve the paging you desire change:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:view.frame];
to:
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, view.frame.size.width, view.frame.size.height)];

Programmatically added subview frames don't show up right in scrollview

I'm creating a scrollView programmatically, and all the views in it. However, when I add more then 1 view, the other views layers don't show up right in their respective frames.
For example:
-(void)viewDidLoad {
[super viewDidLoad];
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
self.scrollView.contentSize = CGSizeMake(self.view.frame.size.width, 150*5);
self.scrollView.backgroundColor = [UIColor lightGrayColor];
self.scrollView.scrollEnabled = YES;
self.scrollView.showsVerticalScrollIndicator = NO;
[self.view addSubview:self.scrollView];
[self setUpLogInButtons];
}
Then I set the subViews to scrollView up here:
-(void)setUpLogInButtons {
CGFloat subviewWidth = self.scrollView.frame.size.width/2;
CGFloat subviewHeight = 150;
UIView *facebookView = [[UIView alloc] init];
facebookView.frame = CGRectMake(0, 0, subviewWidth, subviewHeight);
[facebookView.layer insertSublayer:[self gradientLayerForViewFrame:facebookView.frame withColors:[self colorArrayWithValues:0x4A5C81 v2:0x495B82 v3:0x495B82 v4:0x475B85 v5:0x465B87 v6:0x455A88 v7:0x445A8A v8:0x435A8B v9:0x425A8D v10:0x41598F v11:0x405990 v12:0x3F5992 v13:0x3E5993 v14:0x3D5895 v15:0x3C5896 v16:0x3B5898 v17:0x3A589A]] atIndex:0];
[facebookView addSubview:[self label:self.facebookLabel forView:facebookView withName:#"Facebook" loggedIn:NO]];
[self.scrollView addSubview:facebookView];
}
When it's one subView it works fantastic, when I add the other one it's not right:
-(void)setUpLogInButtons {
...
UIView *facebookView = [[UIView alloc] init];
...
[self.scrollView addSubview:facebookView];
UIView *twitterView = [[UIView alloc] init];
twitterView.frame = CGRectMake(subviewWidth, 0, subviewWidth, subviewHeight);
[twitterView.layer insertSublayer:[self gradientLayerForViewFrame:twitterView.frame withColors:[self colorArrayWithValues:0x2BA8D5 v2:0x28A8D6 v3:0x25A8D8 v4:0x22A8D9 v5:0x20A9DB v6:0x1DA9DC v7:0x1AA9DE v8:0x18AADF v9:0x15AAE1 v10:0x12AAE3 v11:0x10ABE4 v12:0x0DABE6 v13:0x0AABE7 v14:0x08ACE9 v15:0x05ACEA v16:0x02ACEC v17:0x00ADEE]] atIndex:0];
[twitterView addSubview:[self label:self.twitterLabel forView:twitterView withName:#"Twitter" loggedIn:NO]];
[self.scrollView addSubview:twitterView];
}
This one does not show up, the layers specifically are off. However, here is the kicker, the label shows in the right spot because the labels frame is based on it's parent view frame.
-(UILabel *)label:(UILabel *)viewLabel forView:(UIView *)accountView withName:(NSString *)name loggedIn:(BOOL)loggedinStatus {
UILabel *label = viewLabel;
label.frame = CGRectMake(0, accountView.frame.size.height - 50, accountView.frame.size.width, 50);
label.text = [self setAccountLabelForName:name loggedIn:loggedinStatus];
label.textColor = [UIColor whiteColor];
label.textAlignment = NSTextAlignmentLeft;
return label;
}
here is a picture that shows you that the label is based off the parents view frame, and it shows up correctly, but the gradient does not, and it's based off the same frame.
and my gradient method:
-(CAGradientLayer *)gradientLayerForViewFrame:(CGRect)viewFrame withColors:(NSArray *)colors {
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = viewFrame;
gradient.colors = colors;
return gradient;
}
For some reason when inserting my gradient layer to the views layer I had to change it:
//INSTEAD OF THIS:
[... insertSublayer:[self gradientLayerForViewFrame:facebookView.frame...];
//THIS WORKED FLAWLESSLY:
[... insertSublayer:[self gradientLayerForViewFrame:facebookView.bounds...];

iOS Calc X position to place elements on a View

I want to add a Label and an Image in titleView of my NavigationItem. I am adding UILabel and UIImageView to a UIView and setting it as titleView of the navigation Item. Things are being added, but I am not able to calculate the length of label and place image next to it.
My code is :-
// Title Name + Image
UIView *titView = [[UIView alloc] initWithFrame:self.navigationItem.titleView.bounds];
self.navigationItem.titleView = titView;
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(-10, -20, 150, 30)];
title.text = #"Bunny ";
[title setTextColor:[UIColor orangeColor]];
[titView addSubview:title];
float x2 = 30; //+ title.bounds.size.width;
UIImageView *img = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"return" ]];
img.frame = CGRectMake(x2, -20, img.bounds.size.width, 30);
[titView addSubview:img];
I am looking for some way to calc the width text and set accordingly the width of the label. Right now I have set the width of the label as 150. And secondly, calc the x position to place the image just next to the label.
Tried many ways, but nothing works as expected. How can I achieve this ? Can you he give some guidelines such that regardless of length of text of label, things works as expected and UIView gets placed in the center of navigation item.
Any help is highly appreciated. Thanks.
You can call
[title sizeToFit];
after setting its properties and it will size itself to match the contained string.
Set the imageViews x origin to
CGRectGetMaxX(title.frame) + desiredSpacing;
And it could help to subclass UIView to achieve the final results by overwriting layoutSubviews and placing your views there, since the titleView's frame can be adjusted by the navigationBar...basically like this:
#implementation TitleView{
UILabel *_titleLabel;
UIImageView *_img;
}
- (id)initWithTitle:(NSString *)title andImage:(UIImage *)image
{
self = [super init];
if (self) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.text = title;
[_titleLabel setTextColor:[UIColor orangeColor]];
[_titleLabel sizeToFit];
[self addSubview:_titleLabel];
_img = [[UIImageView alloc] initWithImage:image];
[self addSubview:_img];
}
return self;
}
- (void)layoutSubviews{
CGFloat spacingBetweenTextAndImage = 0;
CGFloat width = CGRectGetWidth(_titleLabel.frame)+CGRectGetWidth(_img.frame)+spacingBetweenTextAndImage;
CGFloat x = (CGRectGetWidth(self.bounds)-width)/2;
_titleLabel.frame = CGRectMake(x, (CGRectGetHeight(self.bounds)-CGRectGetHeight(_titleLabel.bounds))/2, CGRectGetWidth(_titleLabel.bounds), CGRectGetHeight(_titleLabel.bounds));
x+=CGRectGetWidth(_titleLabel.bounds)+spacingBetweenTextAndImage;
_img.frame = CGRectMake(x, (CGRectGetHeight(self.bounds)-CGRectGetHeight(_img.bounds))/2, CGRectGetWidth(_img.bounds), CGRectGetHeight(_img.bounds));
}
#end
use in your viewController:
UIView *titleView = [[TitleView alloc] initWithTitle:#"Bunny" andImage:[UIImage imageNamed:#"return" ]];
self.navigationItem.titleView = titleView;

Large UIImage not scaling down into Scroll View's frame

i can't seem to use UIViewContentModeScaleAspectFit property to scale my imageView within my scrollview to fit the scrollview size.
- (void)loadView {
UIImage* image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.moilum.com/images/atomicongallery/setmenu/setmenu1.jpg"]]];
imageView = [[UIImageView alloc]initWithImage:image];
imageView.contentMode = UIViewContentModeScaleAspectFit;
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame];
UIScrollView* scrollView = [[UIScrollView alloc]initWithFrame:applicationFrame];
[scrollView addSubview:imageView];
scrollView.contentSize = image.size;
scrollView.minimumZoomScale = 0.3;
scrollView.maximumZoomScale = 3.0;
scrollView.clipsToBounds = NO;
scrollView.delegate = self;
self.view = scrollView;
}
i have tried imageView.contentMode = UIViewContentModeScaleAspectFill as well. scrollView.contentmode = UIViewContentModeScaleAspectFill as well. All dont seem to work :(
any way out!?
Cheers!
The UIScrollView will not adjust its zoomScale if you don't implement the - (UIView *)viewForZoomingInScrollView:(UIScrollView *)sView method on the UIScrollViewDelegate.
Something like this
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)sView
{
NSArray *subViews = [sView subviews];
if([subViews count] > 0){
return [subViews objectAtIndex:0];
}
return nil;
}
(But apparently not setting a delegate at all works too.)
Have you tried,
-(void)loadView
{
CGRect frame = CGRectMake(0, 0, scrollView.frame.size.width, scrolllView.frame.size.height);
imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.image = [UIImage imageNamed:#"yourimage.png"];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[scrollView addSubView:imageView];
scrollView.contentSize = CGSizeMake( imageView.frame.size.width, imageView.frame.size.height);
}
I write this code from my iPad i think this should work,
Let me know if you have any problem.
Good luck.

Resources