I have a view tableview which display custom cells. Those cells have a UIImageView which need to be scaled if the device is in landscape mode.
I set the autoresizingMask of the tableView to UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth, did the same for my custom cells and the UIImageView.
My problem is that setting autoresizingMask for the UIImageView changes the frame of the view without any rotation of the device needed.
This is my initialisation code for my UIImageView.
- (UIImageView *)bigImageView
{
if (!_bigImageView)
{
_bigImageView = [[UIImageView alloc] initWithFrame:(CGRect){2, [self.header getHeight], 272, 272}];
[_bigImageView setImage:[UIImage imageNamed:#"square.png"]];
[_bigImageView setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
[_bigImageView setBackgroundColor:[UIColor redColor]];
}
return _bigImageView;
}
The width should be 272 but changes automatically to 232.
The result expected with autoresizingMask should be:
But I get:
The ratio is not respected anymore.
This happens because every cell starts with a height of 44 points. You can check that in the init.
Maybe you can correct the size of the cell elements in drawRect: or in layoutSubviews.
Related
I want to put my table view background below the nav bar. When I try to change frame nothing happens..
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, -100, 320, 480)];
imageView.image = self.theme.bgImage;
[self.tableView setBackgroundView:imageView];
In the docs it says:
A table view’s background view is automatically resized to match the
size of the table view.
So I think it's alway resized again by the framework.
Add UIImageview as subview to view and set appropriate image.Place imageview behind tableview. Make tableview background nil. Then try to change frame. This may help you.
I would like to know the best way/correct way to achieve from following layout? I want to place an UIImageView outside of UITableViewCell in a UITableView with static cells.
I have done the following by subclassing UITableViewCell for the cells in section 1 using the following code
- (void)setFrame:(CGRect)frame {
frame.size.width -= 125.0;
[super setFrame:frame];
}
In the UITableViewController's viewDidLoad I add the UIImageView and position it according to the width of the custom UITableViewCell.
This sort of works, but i'm not sure how to deal with rotation and also if what i've done so far would be the correct way?
there are differnt ways to do it. one is to set the width of table view less as you showd in pic 2nd is to use custom table view cell and on required cell add image so that your cell data as well as image will be shown. i think custom cell would be the better solution. tell me if you are asking the same thing what i answered, if no, then i review my answer thank.
I managed to produce what I wanted using the follow, this is proberly not the best way or cleanest way but as no one from StackOverFlow gave any better suggestions I thought I better answer this.
I subclassed the first 3 UITableViewCells and set a frame size to take into account the size of my image.
- (void)setFrame:(CGRect)frame {
float cellWidth = (frame.size.width - 345);
frame.size.width = cellWidth;
[super setFrame:frame];
}
Then in my UITableViewController's viewDidLoad I create and position the UIImageView using the first static cell in the tableview as an IBOutlet ("firstCell"). I then set the autoResizingMask which sorts out rotation and finally add the UIImageView to the view.
//Create and position the image view
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake((firstCell.frame.size.width), (firstCell.frame.origin.y + 70), 300, 137)];
// Add border and round corners of image view to make style look a little like tableviewcells
[imageView.layer setBorderColor:[UIColor colorWithWhite:0 alpha:0.5].CGColor];
[imageView.layer setBorderWidth:2.0];
[imageView.layer setCornerRadius:5.0];
[imageView setClipsToBounds:YES];
//Set the image in the image view
UIImage *image = [UIImage imageNamed:#"defaultPicture.png"];
imageView.image = image;
//Set resizing of image view for when view is rotated
imageView.contentMode = UIViewContentModeRedraw;
imageView.autoresizingMask = UIViewContentModeScaleAspectFit;
//Add tap gesture for imageview to initiate taking picture.
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *imageViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(takePicture:)];
[imageView addGestureRecognizer:imageViewTap];
//Add image view to view
[self.view addSubview:imageView];
This has not been fully tested and i'm sure isn't a great implementation, but its a starting point for the effect i'm after. Please reply if you know of a better way.
Note: The above code is written for my app on the iPad but screenshots are from testing I did on iPhone
What I wanted to achieve here is simply fit the image width to the screen on both orientations and use UIScrollView to just allow scroll vertically to see the whole image.
Both viewController and view are created pragmatically.
The image loaded is larger than screen on both width and height.
Here is the related code in my viewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)loadView {
UIScreen *screen = [UIScreen mainScreen];
CGRect rect = [screen applicationFrame];
self.view = [[UIView alloc] initWithFrame:rect];
self.view.contentMode = UIViewContentModeScaleAspectFill;
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
UIImage *img=[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"image" ofType:#"png"]];
UIImageView *imgView =[[UIImageView alloc] initWithImage:img];
[img release];
imgView.contentMode = UIViewContentModeScaleAspectFill;
imgView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:imgView];
[imgView release];
}
I tried all combinations for both contentMode above, did not give me correct result.
The most close I am getting now: I manually resize imgView in loadView, portrait mode would display correctly since app always starts with portrait mode, but in landscape mode, the width fits correctly, but image is centered vertically rather than top aligned.
If I add the imgView to a scrollView, in landscape mode it looks like contentSize is not set to full image size. but when I scroll bounce I can see the image is there in full size.
Questions:
why I need to resize it manually?
in landscape mode how and where I can 'move' the imgView, so imgView.frame.origin is (0,0) and works correctly with a scroll view?
Update
I added:
imgView.clipsToBounds = YES;
and find out in landscape mode the image bounds is smaller than screen in height.
So the question becomes how to have the image view keeps original ratio (thus shows the full image always) when rotated to landscape? Do I need to manually resize it after rotation again?
Instead of manually take care of orientation change and change view details. I plan to follow Apple document and make separate view controllers for each orientations.
see P42 # ViewControllerProgrammingGuide:
Creating an Alternate Landscape Interface
Here in the code you are not using any scrollView.
You need to add that imageView to ScrollView. and set the scrollView frame as same as the main view and contentSize to imageView or image Size.
If you are using scroll view in the app, then have you also resized the scroll view and the subviews as well, your code if fine just try to resize the subviews as well.
I use the following code to do so.
self.homescroll.autoresizingMask=UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;// | UIViewAutoresizingFlexibleRightMargin |UIViewAutoresizingFlexibleLeftMargin;
self.homescroll.autoresizesSubviews=YES;
[self.homescroll setNeedsLayout];
[self.view addSubview:homescroll];
Just resize the subviews as well.
I have some code that creates a table cell with a slider. It's pretty straightforward and it sizes well on the iPhone. I've anonymized it a bit here:
UITableViewCell* cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Foo"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
CGRect contentViewFrame = cell.contentView.frame;
CGRect sliderFrame = CGRectMake(10, 0, 280, contentViewFrame.size.height);
UISlider* slider = [[UISlider alloc] initWithFrame:sliderFrame];
UIImage* minimumImage = [UIImage imageNamed:#"min.png"];
UIImage* maximumImage = [UIImage imageNamed:#"max.png"];
slider.minimumValueImage = minimumImage;
slider.maximumValueImage = maximumImage;
slider.value = 0.5f;
[slider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:slider];
[slider release];
Of course, this is incorrectly sized for the iPad. So my first thought was to set the autoresizingMask property to UIViewAutoresizingFlexibleWidth. Problem solved, right? Nope. Now on the iPhone, the width of the slider-plus-images content is less than 280 and so it doesn't go right to the end -- it ends up about 20 pixels short.
On the iPad, the same thing -- the width of the UISlider automatically resizes to about 20 pixels short of the end of the cell.
Perhaps the auto resize flag is paying attention to the non-existent accessoryView of the cell? I tried setting it to nil explicitly, but I think it's nil by default, so nothing changed.
I'd like this cell's content to resize automatically to be the "full" width of the cell, regardless of device and orientation. Is there an easy way to do this?
It works exactly how you described. I am inclined to think it's iOS bug. On iPAD when you create new UITableViewCell its width set for 320. hardcoded(!) both view and contentView. It does not resize properly if set to UIViewAutoresizingFlexibleWidth. I had it set to view.frame.size.width/2 with funny results: on iPhone it's 160, on iPad it's 608!!!
I ended up manually resizing my cells and their content.
Bit late but i found the solution of the same question today, but you need to create a custom UITableViewCell.
Then you can overwrite the function
- (void) layoutSubviews
{
[dateLabel setFrame:CGRectMake(10.f, 16.f, 80.f, 12.f)];
[textLabel setFrame:CGRectMake(106.f, 16.f, contentView.frame.size.width-105.f + 1.f, 12.f)];
}
In that function the self.frame.size.width is the actual one.
And it works with rotation of the device, too.
You should be able to tell the resizing system to "stick" the object a fixed distance from the right edge (where it's not resizing far enough). If you experiment with IB you can create a view that resizes in width and is fixed to the right side.
Do you have UIViewAutoresizingFlexibleRightMargin set as well?
Set your cell's contentMode to UIViewContentModeRedraw.
Setup: I have a UITextView inside a UITableViewCell's contentView. I want it to take up the full size of the cell. I create the text view like so:
UITextView *textView = [[[UITextView alloc] initWithFrame:CGRectMake(0,0,268,43)] autorelease];
textView.backgroundColor = [UIColor redColor];
textView.layer.cornerRadius = 10;
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
And I override heightForRowAtIndexPath to return 200 for that row.
The background color is just so I can tell where it is. The cell seems to be automatically sizing it correctly upon first view. However, I need it to continue to resize it correctly while autorotating the interface, which only seems to work sometimes, and only when I'm not editing the textView. Other times, it resizes the view to have a very small height (looks like -1), or makes it too wide, or just doesn't even resize it at all.
I've tried overriding layoutSubviews in the cell and just do nothing, but even that doesn't stop the view from resizing all over the place.
I've been hacking away at this for awhile now, but still have found no solution.
A UITableViewCell has a fixed height, the height provided by the UITableView's delegate. When you rotate your device, the height of the row will never change, unless you call -reloadData on your tableView. I'd get rid of the autoresizing and manage it yourself.
When you init your textField, you can easily set the frame to CGRectZero. Then implement -layoutSubviews (and call super in that method, before setting the frames of your subviews) and set the frame of the UITextField according to the contentRect property of the cell.
- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {
if(self = [super ...]){ // or -initWithStyle:reuseIdentifier: whatever you want
_textView = [[UITextView alloc] initWithFrame:CGRectZero]; // Instance variable
// Probably not needed to set autoresizing mask
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
_textView.frame = CGRectMake(0.0f, 0.0f, self.contentRect.size.width, self.contentRect.size.height); // Adjust as needed
}