i have a tableview(no table view cell). My Application is running fine in iOS 6 but when i am running it in iOS7 Tableview margin is conflicting.When i am setting up frame via Code its margin is only adjusting from left and bottom. i am using following code
if([[[UIDevice currentDevice]systemVersion]floatValue]>=7){
CGRect newSize = CGRectMake(0,0,730,925);
newSize.origin.y = 0;
newSize.size.width = 728.0;
newSize.size.height = 925.0;
self.myTable.frame = newSize;
}
Please suggest me something how can i resolve it
?
Here are images for ios 6 & ios 7 (Its a group table view ) i havent changed any margin for ios 7 its same as in ios6 ,and if i am doing any changes in ios 7 regarding margin its affecting in ios 6 layout too..
Add autoresize property
//ensure autosizing enabled
self.view.autoresizesSubviews = YES;
myTable = [[myTable alloc]initWithFrame:self.view.bounds];
[myTable setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
[self.view addSubview:myTable];
Related
I can't seem to get AutoLayout working on my Table View Cells.
On some cells it seems to work, and on others it seems to not work. Even cells of the exact same kind.
For example, on some cells the Description will be more than 1 lines worth of text and it will work correctly...
...Yet on other cells the Description will be more than 1 lines worth of text but only show 1 line of it with a bunch of empty space.
Can you help me figure out what I'm missing or doing wrong? Thanks!
I'm using this StackOverflow question to guide my process as a first-timer doing this: Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
1. Set Up & Add Constraints
These are working well for the most part I believe.
2. Determine Unique Table View Cell Reuse Identifiers
I'm not totally sure if I need to worry about this part since I will always have a Headline, Time, and Description.
For iOS 8 - Self-Sizing Cells
3. Enable Row Height Estimation
I added this to viewDidLoad:
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 180.0;
UPDATE: Adding more info per Acey request
To be clear, I put constraints:
Headline: 15 left, 85 top, 15 right
Vertical Spacing between Headline and Time, of 10
Vertical Spacing between Time and Description, of 10
I Cmd clicked all three labels and added Leading Edges and Trailing
Edges
I pinned 20 between Description and the bottom of the Table View Cell
UPDATE 2: Solved
Answer below worked really well, but also any extra spacing was due to height set for cell being too large, so Xcode was automatically adding extra space to fill out height of cell since text labels didn't fill out the full height of the Table View Cell.
Let me know if you have any questions or need any help on this if you come across this and have the same problem.
Thanks everyone!
I haven't tried using the new iOS 8 mechanisms yet. But I have faced similar issues when I was doing this with iOS 6 / 7. After updating the app to iOS 8 it still works fine, so maybe the old way is still the best way?
I have some examples of my code here:
AutoLayout multiline UILabel cutting off some text
And here:
AutoLayout uitableviewcell in landscape and on iPad calculating height based on portrait iPhone
Long story short the pre iOS 8 way involved keeping a copy of a cell just for calculating the height inside tableView:heightForRowAtIndexPath:. But this wasn't enough for dealing with multi line UILabel's. I had to subclass UILabel to update the preferredMaxLayoutWidth every time layoutSubviews was called.
The preferredMaxLayoutWidth "fix" seemed to be the magic secret I was missing. Once I did this most of my cells worked perfectly.
The second issue I had only required me to set the content compression resistance and content hugging properties correctly, so for example telling the label to hug the text will mean it won't expand to fill the whitespace which will cause the cell to shrink.
Once I did these 2 things my cells now handle any font size, or any amount of text without any messy layout code. It was a lot to learn but I do think it paid off in the end, as I have a lot of dynamic content in my app.
Edit
After coming across a few issues of my own with iOS 8, i'm adding some more details to solve these very odd autoLayout bugs.
With the code I mentioned, it doesn't seem to work when the cell "Row Height" is not set to custom. This setting is found in IB by selecting the cell and clicking the autoLayout tab (where all the content compression resistance settings etc are). Press the checkbox and it will fill with a temporary height.
Second is, in my code I keep a local copy of a cell, and then reuse it many times inside the heightForRowAtIndexPath: method. This seems to increase the cell height by a lot every time it is called. I had to re-init the local copy by calling:
localCopy = [self.tableView dequeueReusableCellWithIdentifier:#"mycell"];
It appears the new Xcode 6 / iOS 8 changes are very much so not backwards compatible with iOS 7 and it seems to be managed quite differently.
Hope this helps.
Edit 2
after reading this question: iOS AutoLayout multi-line UILabel
I've come across another issue with iOS 7 / iOS 8 autolayout support!!! I was overriding layoutSubviews for iOS 8 I also needed to override setBounds to update the preferredMaxLayoutWidth after calling super. WTF have apple changed!
Seems to be an issue with the setting in IB for preferredMaxLayoutWidth, because iOS 7 can't use the automatic feature, if you use the same UILabel on multiple devices, its only going to use the 1 width. So UITableViewCell's on an iOS 8 tablet will be bigger because the same cell needs to have 2 lines on an iOS 8 iPhone.
Here is my attempt.
You could create a method/function that get's you the cellview that you need. Like so:
- (UIView *) getCellView {
UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 0.0f)];
cellView.tag = 1;
cellView.backgroundColor = [UIColor clearColor];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(15.0f, 10.0f, 15.0f, 15.0f)]; //I assumed that was the size of your imageView;
imgView.image = [UIImage imageNamed:#"whatever-your-image-is-called"];
[cellView addSubview:imgView];
CGFloat xPadding = 15.0f;
CGFloat yPadding = 15.0f;
UILabel *headlineLabel = [[UILabel alloc ]initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.width - (xPadding*2), 0.0f)];
headlineLabel.numberOfLines = 0;
headlineLabel.text = #"Red Sox season fell apart after World Series title (The Associated Press)";
[headlineLabel sizeToFit];
CGRect hFrame = headlineLabel.frame;
if(hFrame.size.width > self.view.frame.size.width - 31.0f)
hFrame.size.width = self.view.frame.size.width - 30.0f;
hFrame.origin.y = imgView.frame.size.height + yPadding;
headlineLabel.frame = hFrame;
UILabel *timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height-(xPadding*2), 0.0f)];
timeLabel.text = #"4h";
//timeLabel.numberOfLines = 0; //uncomment if it will wrap on multiple lines;
[timeLabel sizeToFit];
hFrame = timeLabel.frame;
if(hFrame.size.width > self.view.frame.size.width - 31.0f)
hFrame.size.width = self.view.frame.size.width - 30.0f;
hFrame.origin.y = headlineLabel.frame.size.height + yPadding;
timeLabel.frame = hFrame;
UILabel *descriptLabel = [[UILabel alloc] initWithFrame:CGRectMake(xPadding, 0.0f, self.view.frame.size.height - (xPadding*2), 0.0f)];
descriptLabel.text = #"Boston (AP) -- To Boston Red Sox manager John Farrel, it hardly seems possible that just 11 months ago his team was celebrating the World Series championship on the field at Fenway Park.";
descriptLabel.numberOfLines = 0; //I would suggest something like 4 or 5 if the description string vary from 1 line to more than 5 lines.
[descriptLabel sizeToFit];
hFrame = descriptLabel.frame;
if(hFrame.size.width > self.view.frame.size.width - 31.0f)
hFrame.size.width = self.view.frame.size.width - 30.0f;
hFrame.origin.y = timeLabel.frame.size.height + yPadding;
descriptLabel.frame = hFrame;
cellView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, descriptLabel.frame.origin.y + descriptLabel.frame.size.height + 15.0f /*some padding*/);
return cellView;
}
If you are using indexPath.row, you could just change the method name to be - (UIView *)getCellView:(NSIndex) *indexPath and it should work the same.
Then in your heightForRowAtIndexPath you could do
return [[self getCellView] frame].size.height;
or
return [[self getCellView:indexPath] frame].size.height
And in your cellForRowAtIndexPath you could just do the following
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.text = #"";
cell.detailTextLabel.text = #"";
}
[[cell viewWithTag:1] removeFromSuperview];
[cell addSubview:[self getCellView]; //or [cell addSubview:[self getCellView:indexPath]];
return cell;
Hope this helps. Let me know if something was unclear or not quite working. There are some stuff you may need to tweak to fit your usage, especially in cellForRowAtIndexPath, but that should be more or less everything you need to get going. Happy coding.
I have a iphone app which is installed in iPad its UI(blank space about 20 pixels above navigation bar) is correctly displayed in ios6 while a blank space appears in ios7 in iPad.
I tried using the default images and using the methods
- (void) viewDidLayoutSubviews {
if (([[UIDevice currentDevice].systemVersion floatValue] >= 7.0)) {
CGRect viewBounds = self.view.bounds;
viewBounds.origin.y = -20;
self.view.bounds = viewBounds;
}
}
but no use.How do i fix it? It is not a universal app.
The problem is related on the way iOS7 draws the views, please rewfer to these guide to understand the problem:
Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7
I have a UITextView that should consume the height of the screen, minus the height of the nav bar and keyboard (as when the view loads the keyboard appears). Obviously on a 4 inch device this means the text view should be slightly taller. Is it possible in Interface Builder to make the height device dependent?
If not, can I do it in code? Is it possible to do without some Auto Layout constraints?
It would be very easy to do it by using Auto Layout constraints. Is there any special reason for not using it?
You need to do this check in your code, You can use below Macor to check the device:
#define IS_IPHONE5 ([[UIScreen mainScreen] bounds].size.height == 568)?TRUE:FALSE
then:
if (IS_IPHONE5 )
{
//textView.frame = ..
}
else
{
//textView.frame = ..
}
And yes you can do it using a couple of Auto Layout constraints which is the best practice to do that, check this SO question:
iPhone 4 & 5 Autoresize Vertical Space
you can use struts and springs. but auto layout is the new hotness.
iOS AutoLayout vs Springs & Struts
Going off null's answer:
Im assuming you are placing this UITextView inside a UIViewController?
You can set the frame for the UITextView at runtime.
In viewDidLoad:
-(void)viewDidLoad {
UITextView *textView = [[UITextView alloc] init];
//216 is the height of the keyboard, 20 is the height of the status bar
if (isiPhone5) {
CGRect frame = CGRectMake(0, self.navigationBar.frame.size.height + 20, self.frame.size.width, 568-216);
[textView setFrame:frame];
}
else {
CGRect frame = CGRectMake(0, self.navigationBar.frame.size.height + 20, self.frame.size.width, 480-216);
[textView setFrame:frame];
}
}
In iOS 6 and earlier a uitableviewcell's imageView was positioned all the way over to the left with a 0 offset. In iOS 7 though this has been changed and there is now a 15 point space now. I would like to position the imageView like it is in iOS 6. I'm already subclassing the uitableviewcell with AKHighlightableAttributedCell to deal with attributed text not being highlighted. So based on some searching I added:
- (void) layoutSubviews
{
[super layoutSubviews];
// Makes imageView get placed in the corner
self.imageView.frame = CGRectMake( 0, 0, 80, 80 );
}
The issue is everything else still doesn't get repositioned and so I'm thinking there must be a better way to do this. I'd read some people mentioning using a negative offset to move everything over but I wasn't sure how this would work with constraints as it needs to scale properly for each orientation. Is there an easier solution to this that I'm missing? Thank you.
It appears I was doing it the correct way. The missing piece regarding the divider between fields was setting the inset on iOS 7. You can do this in the viewdidload or viewwillload and set self.tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0);
You will need to add a check if running iOS 7 or newer as this is a new property I believe. A better option might be setting it in the storyboard by selecting the table view and then setting separator insets from default to custom.
Here is the layoutSubviews method that repositions imageView and textLabel. If you have a description add that as well.
- (void) layoutSubviews
{
[super layoutSubviews];
// Makes imageView get placed in the corner
self.imageView.frame = CGRectMake( 0, 0, 80, 80 );
// Get textlabel frame
//self.textLabel.backgroundColor = [UIColor blackColor];
CGRect textlabelFrame = self.textLabel.frame;
// Figure out new width
textlabelFrame.size.width = textlabelFrame.size.width + textlabelFrame.origin.x - 90;
// Change origin to what we want
textlabelFrame.origin.x = 90;
// Assign the the new frame to textLabel
self.textLabel.frame = textlabelFrame;
}
This question already has answers here:
How to develop or migrate apps for iPhone 5 screen resolution?
(30 answers)
Closed 8 years ago.
How do I resize a text view so that it expands when displayed in the new 4" screens that it isn't shorter? I'm using AutoLayout. Also, I calculated that since the iOS keyboard takes up 216 points on both devices, and since the Navigation bar takes up 44 points on both devices, that the remaining view would be 200 points on a 320x460 screen. But how do I set this relative to the iPhone 5 screen? Any help would be appreciated. I've provided a screenshot to illustrate what I mean to better understand my issue.
Normal Screen (Works great!):
iPhone 5 Screen (Not so great!):
Try do like this:
self.view.autoresizesSubviews = YES;
self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
Just ended up disabling autolayout for that specific view controller, and set my own CGRect.
CGRect largeScreen = CGRectMake(0, 1, 640, 290);
CGRect screenBounds = [[UIScreen mainScreen]bounds];
if (screenBounds.size.height==568)
{
[self.htmlText setTranslatesAutoresizingMaskIntoConstraints:YES];
htmlText.frame = largeScreen;
}
It is quite simple calculate height of textfield like this
CGFloat TextFieldHeight = self.view.frame.size.height - keyboardHeight- statusbarheight - navigationBarHeight;
Then assign this height to your textfield.
CGRect TextFieldNewFrame = textField.frame;
TextFieldNewFrame.size,height = TextFieldHeight;
textField.frame = TextFieldNewFrame;