Objective C / Autoresizing subviews not working - iphone

So, I'm trying to make a calendar from an image.
Images are in higher resolution then the screen, so I thought about loading the image to a larger view, adding everything to it (as subviews), resizing the view to fit the screen to show the user, then if he decides to save the image, resizing it again to a larger size and saving it. (It's mostly working as I intended).
The problem I'm having is the subviews I add to my ImageView won't resize.
Loading the image to my ImageView and enabling AutoresizesSubviews:
[self.backgroundImageView setImage:backgroundImage_];
[self.backgroundView setAutoresizesSubviews:YES];
Adding a UILabel on it:
UILabel *calendarLabel = [[UILabel alloc] initWithFrame:CGRectMake(screenWidth_ * 0.1, 0, screenWidth_ * 0.8, screenHeight_ * 0.15)];
[calendarLabel setText:#"Calendar"];
[calendarLabel setTextColor:[UIColor whiteColor]];
[calendarLabel setTextAlignment:NSTextAlignmentCenter];
[calendarLabel setBackgroundColor:[UIColor clearColor]];
[self.backgroundImageView addSubview:calendarLabel];
Saving the size it should be resized to:
savedRect_ = self.backgroundView.frame;
Resizing the imageview (actually resizing the parent of the imageview, since imageView occupies the whole view):
[self.backgroundView setFrame:savedRect_];
Now I have no idea why this isn't working as I intended it.
PS: Did some testing and it turns out it's a little different with the programmatically added views then the ones added with IB. I have a feeling it has to do with AutoresizingMask.
Did some research, and I would imagine I have to make everything flexible (it can grow in width, height, size on top, bottom, right and left sides), but it's still isn't working. If I enable all the 6, the view just doesn't move.
Could anyone tell me what setting I need to make so the views stay at the same position related to their parent View?

Ok, turned out to be an easy solution as I expected...
I tried applying each mask separately:
[calendarLabel setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin];
[calendarLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
....
Instead of:
[calendarLabel setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin];

Related

how can i use UISCrollView paging with different heights?

I have a UIScrollView which shows multiple images when user swipe horizontally. But these images does not have the same height. The first image has height taller then the second.
1.What I want to do is when the person swipes, the next picture shown, is positioned at the top.
2.Also when using ScrollView's paging, the vertical scrolling is not smooth, it skips a whole frame. I've read that i cannot use ScrollView's paging to get the vertical scrolling smooth.
Any ideas?
For the 1st problem should I load nibs with images inside? How do I load a nib after swiping?
updated question:is there a way, i can load nibs(with its own scroll and imageview inside) as i swipe from left to right or right to left? because loading images side by side in the uiscrollview isn't going to do the trick.
set
[imageView setContentMode:UIViewContentModeScaleAspectFit];
this will show the image in proper aspect ... you don't have to worry about image size
[imageView setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin];
this will keep your imageView attached to the top of scrollView.
If you want every image to show at the top of the scrollView adjust the image.frame accordingly.
UIImageView *imageView;
UIImage *image = [UIImage imageWithData:loadTheImage];
imageView.image = image;
imageView.frame = CGRectMake(0, 0, 280, 480);
In the CGRectMake the first two values specify the padding for the image. The first is x value, the second y value. If both are 0, the image is displayed in the top left.
Does this make sense?

iPhone Horizontal Scrolling

I am trying to create an app with horizontal scrolling, so that one would be able to scroll horizontally through a series of images. I watched the WWDC Session 104 video on this, and while they made an interesting app, they flew through the basics of it very quickly.
I understand using the UIScrollView, and that I have to enable paging. After that they say that I should add more views as subviews of the scrollview, but I am not clear on how to do that. I am also not clear on how I add my images to those views.
As you can probably tell I am pretty new at this so any help would be appreciated.
You want to look into UIImageView. It's a view specifically for holding images.
When you add your images, you want to set their rects (probably using initWithFrame: for each UIImageView) so that:
the first image is at 0,0
the second image is at 320,0
third is at 640,0 (etc)
I.e. each image is 320 pixels right of the previous.
The final step is to set the contentSize for your UIScrollView -- this is a CGSize which describes the total size of the scroll view.
If you have 3 images, you would then set it to (320*3) * 480 using e.g.
myScrollView.contentSize = CGSizeMake(320*3, 480);
A lot of people, when they initialize the scroll view, have a for loop or similar which steps through the images they want to display. These for loops tend to look something like this:
CGFloat scrollWidth = 0.f;
for (UIImage *someImage in someNSArrayWithImages) {
UIImageView *theView = [[UIImageView alloc] initWithFrame:
CGRectMake(scrollWidth, 0, 320.f, 480.f)];
theView.image = someImage;
[myScrollView addSubview:theView];
[theView release];
scrollWidth += 320.f;
}
myScrollView.contentSize = CGSizeMake(scrollWidth, 480.f);
This way you'll get things lined up and you'll get the content size for you at the same time.
If you want to make it so that the scroll view "intelligently" scrolls to each image and stops when people slide left/right, you can do myScrollView.pagingEnabled = YES.
Hope that helps get you going.
Assuming you have "infinite" images, putting them all there at or before launch time in a huge UIScrollView will not be an option. (there is a limit to the size of a UIView)
The way I solved it: Make a UIScrollView covering the whole screen. It's content should be a UIView of 3*320 width and 480 height, extending 320px left and 320px right.
Put 3 UIImageView's in it, left, middle and right. Set paging=YES, so the uiscrollview clips to the 3 "pages" you've created.
Make sure your class is the delegate of the uiscrollview, and listen for
-(void)scrollViewDidEndDragging:(UIScrollView*)sv willDecelerate:(BOOL)notFinished
-(void)scrollViewDidEndDecelerating:(UIScrollView*)sv
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView*)sv
and make the appropriate transitions on hitting paging boundaries; shift images and set ContentOffset so you're looking at the center image again.
I suggest you make this first, and only then read on...
Then you will hit on a bug, documented here UIScrollView - (bounces = NO) seems to override (pagingEnabled = YES) and here http://www.iphonedevsdk.com/forum/iphone-sdk-development/935-paging-uiscrollview.html, which makes that you cannot disable bouncing and have paging enabled at the same time. So enable bouncing, and subclass UIScrollView, overruling setContentOffset in there to prevent bouncing. (having bouncing really enabled will make for a rather unusual user experience)
Have a look at Apple's PageControl sample code. It's fairly short and easy to follow so you'll get the gist of setting up a project where multiple view controllers are loaded as you swipe horizontally.
Once you have this setup then it's the view controller's responsibility to load its own content (in your case, an image). You should make sure you understand how to load images first (using threads, etc) before you tackle paging, etc.
Think of it as two independent tasks. The view control is responsible for loading and displaying an image. The scroll view with paging just tells the appropriate view controller when to load itself (it doesn't care what the view controller does once its loaded)
Good luck!

How do you adjust the frame or vertical alignment of a UIBarButtonItem contained by a UIToolbar instance?

Horizontal positioning of UIBarButtonItems is no problem, I can simply pad the space with fixed/flexible space items. However, I can't seem to adjust the toolbar item vertically. UIToolbar has no alignment property, and UIBarButtonItem has no way of setting its frame.
I need to do this because we're using a mix of custom icons created using initWithImage, and standard icons created with initWithBarButtonSystemItem. The custom icons aren't being centered properly (they're offset upwards, relative to the system icons, which are centered properly), so the toolbar looks awkward.
Yes, imageInsets worked fine for me!
float topInset = 4.0f;
myUIBarButton.imageInsets = UIEdgeInsetsMake(topInset, 0.0f, -topInset, 0.0f);
moves the image 4 pixels down.
AVOID THIS:
float topInset = 4.0f;
myUIBarButton.imageInsets = UIEdgeInsetsMake(topInset, 0.0f, 0.0f, 0.0f);
moves the image 4 pixels down (BUT rescales the image height so it looks compressed).
imageInsets property of UIBarItem?
Doesn't seem to be any simple, clean way of doing this, so I went with an ugly but functional hack: nesting. I stuck another UIToolbar containing the button into a UIView which I set as a UIBarButtonItem on the original toolbar using initWithCustomView. The second UIToolbar can move freely within the UIView, and the actual icon retains all the properties of a UIBarButtonItem.
Ugh.

How do I control the position of an image in a grouped tableview cell?

For some reason, I can not seem to change the default position of an image in a grouped tableview cell.
In the cellForRowAtIndexPath method I use the following to load the image:
cell.imageView.image = [UIImage imageWithContentsOfFile:MainImagePath];
I've been experimenting with the following to adjust the position of the image but have had no luck.
cell.contentMode = UIViewContentModeCenter;
I've also tried this with no luck.
cell.imageView.contentMode = UIViewContentModeCenter;
Can you use the frame of the imageView ie:
cell.imageView.frame = CGFrameMake(0.0, 0.0, 20.0, 20.0);
or set the center of the imageView with
cell.imageView.center = CGPointMake (20.0, 10.0);
=Seth
EDITED: Thanks Jonah, I fixed that!
The default layout of UITableViewCell is [imageView][textLabel][accessoryView]. You can't change that.
If you want to arbitrarily position an image in your UITableViewCell you must add a UIImageView to the cell's contentView.
To move the imageView, you need to change it's frame. The things you're doing are just reconfiguring how it responds to view resizing. Try setting cell.imageView.center to the new center you want.
You should be aware of tableView:willDisplayCell:forRowAtIndexPath:. This is called immediately before displaying the cell, and is your last (and often best) chance to establish layout. tableView:cellForRowAtIndexPath: is called much earlier and its results are cached. So the layout may be wrong by the time it's actually displayed (due to view resizing for instance). That's why we generally do layout in tableView:willDisplayCell:forRowAtIndexPath:.

UIView subclass won't autoresize

I've been looking for background information on resizing, but I haven't been able to find much. I know I need to set autoresizesSubviews on the superview and autoresizingMask on the subview.
I have done this, and my UIImageViews properly resize, but my custom UIView subclass does not.
The code for the UIImageView:
UIImageView *newX = [[[UIImageView alloc] initWithImage:dot] autorelease];
[newX setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[newX setFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)];
[self.view addSubview:newX];
The code for the custom UIView subclass:
trace = [[TraceView alloc] initWithFrame:self.view.bounds];
[trace setAutoresizingMask:(UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin)];
[self.view addSubview:trace];
From what I can tell, the view rotates as expected, but does not resize. I can no longer see the bottom of it, and it doesn't fill the screen to the right.
Do I have to add anything to the UIView subclass to make resizing work properly?
EDIT:
I've changed the autoresizingMake to (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight) and called [subview setNeedsDisplay]; I'm not sure why this is necessary as the UIImageViews work fine without it, but it now behaves as expected.
I think you're missing UIViewAutoresizingFlexibleHeight or width on the subview. Otherwise I think the view just moves around according to the margins but doesn't resize.
You mention rotation. Is the superview that contains your custom view actually resizing correctly? If in doubt, set its background to some odd color. If it did not resize correctly after the orientation change then you should see a white or grey bar on the right.