How to set views frame without auto layout - iphone

With the release of iOS 6 I changed my applications storyboard to use the new auto layout feature.
My problem is that I set a tableview frame in one view controller - but when I use the auto layout feature the table.frame = CGRectMake(..) code seems to get ignored.
My app should change the tableview frame if there is iAd or no iAd.
I dont know if i can solve this problem with auto layout - maybe you can help me.
greetings from germany :)

I know this is old but with the move to iOS7 I felt it was time to activate auto-layout for my own apps. I ran across this and found that I could simply turn auto-layout back on and put your table.frame = CGRectMake(..) code into:
- (void) viewDidAppear:(BOOL)animated
{
table.frame = CGRectMake(..)
}

Don't use the auto layout and remove the UIViewAutoresizingFlexibleWidth and UIViewAutoresizingFlexibleheight in the xib. Let me know if you didn't get it.
And use the set frame property in the code.

Related

UITableView not scrolling after switching to iOS 7

In iOS 6, I had a UITableView created using QuickDialog in my app. It scrolled normally. When I switched to iOS 7, the same UITableView does not scroll properly. I can drag to the bottom (the scroller compresses) but when I release, it pops back up the to the top. I've been playing with viewDidAppear to try and diagnose the problem. See the code block below.
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"Content height: %f",self.quickDialogTableView.contentSize.height);
[self.quickDialogTableView reloadData];
NSLog(#"Content height: %f",self.quickDialogTableView.contentSize.height);
[self.quickDialogTableView layoutIfNeeded];
NSLog(#"Content height: %f",self.quickDialogTableView.contentSize.height);
}
The output of this block in iOS 7 is
Content height: 0.000000
Content height: 836.000000
Content height: 0.000000
Meanwhile, the output of this block in iOS 6 (simulator) is
Content height: 836.000000
Content height: 836.000000
Content height: 836.000000
Also to try and diagnose the problem, I set up a button that would trigger [self.quickDialogTableView reloadData]. Whenever that button is pushed, the scrolling behavior begins to function normally. Then when I leave the view and come back, the scrolling fails again (until the button is pushed). To be clear, I have tried to put a reloadData in viewWillAppear by itself (i.e., removing the last two lines in the code block above) and it does not correct the scrolling.
I'm looking for clues as to where I might look to correct the issue. Thanks in advance for any help.
Okay, so I couldn't figure out the source of the problem but I did find a workaround that I hope helps someone else. Or at least, maybe helps someone else point out what's really wrong.
I created a property called trueContentSize where I store what the correct size is.
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.quickDialogTableView reloadData]; // Calculates correct contentSize
self.trueContentSize = self.quickDialogTableView.contentSize;
}
Then, in -viewDidLayoutSubviews I correct the contentSize manually.
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.quickDialogTableView.contentSize = self.trueContentSize;
}
Just thought I might throw in my two cents here..
Same problem was happening to me. Table loads fine at first, but navigate to a different screen, come back, and the table view's contentSize is 0,0 and unscrollable. Fausto's workaround wasn't reliably working, either.
What turned out to be the case for me was just the act of referencing topLayoutGuide in -viewWillLayoutSubviews. Doing that causes all of the above symptoms. Try it out in a new project:
Setup a table view controller inside a tab controller.
Give it 30 rows with just static content.
Run and you can scroll. Switch tabs, then back, and you can scroll.
Add NSLog(#"%#", self.topLayoutGuide); in -viewWillLayoutSubviews
Run again, you can scroll, but switch tabs, no more scrolling.
Weird. Sounds like an iOS bug, or you just shouldn't reference topLayoutGuide in that method. Removing any reference to that property will fix the issue.
Edit: As of earlier this year, Apple confirmed via a Radar report I made this is an iOS bug. Don't reference topLayoutGuide until it's been resolved (whenever that will be, heh). :)
This is my current temporary fix. Anyone figure out the real fix?
#interface UITableView (Extension)
#end
#implementation UITableView (Extension)
- (void)setContentSize:(CGSize)contentSize {
if (contentSize.height != 0) {
[super setContentSize:contentSize];
NSLog(#"set content height %f", contentSize.height);
} else {
NSLog(#"set content size zero");
}
}
#end
Faced the same problem and the only solution found was to reload the data in the table. Hope that helps.
I had a similar issue. My issue was that I had an explicit height set for the table view in the storyboard. Updating my table view to make use auto layout by setting distance to the views above / below made it work for me.

EXC_BAD_ACCESS on setCollectionViewLayout

If I change the layout of a UICollectionView during an orientation change, I get EXC_BAD_ACCESS after a few rotations.
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
UICollectionViewLayout *layout = [[UICollectionViewFlowLayout alloc] init];
self.myCollectionView.collectionViewLayout = layout; // This causes EXC_BAD_ACCESS after a few rotations
}
Is this a UICollectionView bug? Or am I doing something wrong? If it's a bug, is there any way to change the whole layout during an orientation change?
I noticed that the same problem is mentioned in this answer. Debugging with NSZombies does not produce additional information.
Not quite sure it has something to do but the Release Notes for iOS 6 say:
The willRotateToInterfaceOrientation:duration:,
willAnimateRotationToInterfaceOrientation:duration:, and
didRotateFromInterfaceOrientation: methods are no longer called on any
view controller that makes a full-screen presentation over itself—for
example, presentViewController:animated:completion:
You should make sure that your apps are not using these methods to manage the layout of any subviews. Instead, they should use the view
controller’s viewWillLayoutSubviews method and adjust the layout using
the view’s bounds rectangle.
Since you are using UICollectionView maybe it has something to do that you are using this method to change its layout.

Fixed Background for iPhone app using Storyboard

Can't seem to find a way to fix a graphic - a light graphic that would remain static as the user navigates from scene to scene. Have been combing forums for a few days, but most answers point to MainWindow.xib, which isn't generated for a storyboard project. Would appreciate any advice.
Here’s what I was able to cobble together thanks to advice from #Max. Like I said, very new to this, so if this code needs tuning please leave a comment so I don’t lead others astray.
Add the image to the app’s main window in the AppDelegate’s didFinishLaunchingWithOptions method :
UIImageView *myGraphic = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"myGraphic.png"]];
[self.window.rootViewController.view addSubview: myGraphic];
[self.window.rootViewController.view sendSubviewToBack: myGraphic];
Then, to make your views transparent so the background shows through - in your viewController class/es, add to viewDidLoad method:
self.view.backgroundColor = [UIColor clearColor];
(And note if you try to decrease the transparency through the alpha property for the view via the Attributes Inspector, it will make everything transparent on that view -buttons, etc - that’s why it needs to be done programmatically.)
Sure, it’s not thoroughly tested. But for now it’s working and it’s a thing of beauty. Thanks all.
You can try to manually add UIImageView to your window and then set 0 background transparency
for all other views.
One way to do it -- it may not be the best -- can be that you subclass a UIView, and set the UIView instance in all of your viewControllers in the storyboard an instance of your cutomized UIView class, which contains your graphic as a background.
If you're going to tackle this programmatically, within each view controller, set:
[[self view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]]];
in viewDidLoad
I'm sure some tweaking would allow you to apply this principle throughout the program from the app delegate, or by using a singleton.
Using this solution, though, you're still going to have to make some method call within each view controller where you want this style applied.

iOS 5 issues: Navigation bar clipped after dismissing modal

I have a nice little app on the app store that does pretty well for itself. Life was great until iOS 5 came to town. Now, I have a number of issues with my app that I have no way of fixing because I have no clue what is going on, because I feel that they are iOS 5 issues, not mine.
Was there an iOS 5 conversion manual I missed? Or did they just change everything for fun, and want us to figure out where all the easter eggs were?
Here is another issue I am experiencing (that I have wasted so much time trying to fix), that DON'T EXIST AT ALL when I simply say that I want to run the app in good ol' 4.2:
Modal view
My app is a simple reader app. I have a book reading view that displays text with a UIWebView. One of the features I have been working on involves the ability to take notes as you read. This is achieved by hitting a button, and presenting a modal view. Yes, a modal view. The most simple pre- iOS 5 thing you could possibly do. Now, when I dismiss my modal view, just by hitting cancel, and simply dismiss the view, when I get back to my reader view, the navigation bar at the top is pushed up half way off the screen! This doesn't happen in 4.2, but there it is in iOS 5!
What can I do to get this issue resolved?
Thanks for your help.
Ok, I was just able to figure out what in the blazes was going on. I had the shouldAutorotateToInterfaceOrientation value set to a BOOL variable, so that when the modalView was coming back, it didn't know the state/size of the status bar. Fixed that, and the problem disappeared.
I have the feeling it has something to do with the way you present and dismissing the modalview. Apple introduced a new method to present views. May you try using theses instead of the old ones and see if it fixes your problem.
So here is what you do:
change this method:
presentModalViewController:animated:
into the new preferred method introduced with iOS 5:
presentViewController:animated:completion:
Depending if you are using dismissModalViewControllerAnimated:to dismiss your view, change it into dismissViewControllerAnimated:completion.
This methods also have completion handler which is very useful to do some extra work after the view has been presented/dismissed. Maybe that also helps with your other issue. Let me know if that might helped.
A major change in iOS 5 is that the navigationController property of UIViewController is no longer set for modal views. Instead, there is a new (not present in iOS 4) parentViewController property. So where you're using navigationController in a modal view you need to change the logic to something like:
UIViewController* parent;
if ([self respondsToSelector:#selector(parentViewController)]) {
parent = self.parentViewController;
}
else {
parent = self.navigationController;
}
(That's from memory, so I can't guarantee that every t is dotted and every i crossed.)
I was seeing this same clipping problem.
I found out that the reason for my issue was that I set the content size within the modal dialog (something I did for my iPad layout), so removing these two lines seemed to fix the issue:
CGSize size = CGSizeMake(320, 480);
self.contentSizeForViewInPopover = size;
I thought the problem was fixed but it wasn't. After reviewing the code some more, cleaning the build, and retesting it turned out to be a shouldAutorotateToInterfaceOrientation which would return NO for all orientations, for a brief amount of time (flag == NO) while the app is loading (root controller). You want to at least return YES to one orientation like so:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return !self.flag ? UIInterfaceOrientationPortrait == toInterfaceOrientation : YES;
}

UINavigationItem#titleView alignment problems

I am finding little information about using UINavigationItem#titleView with a custom font.
When I have done so, the font is misaligned vertically in the navigation bar.
This entry is partly to document a hack, and also hoping someone has a succinct answer to this problem, as I feel I am missing something simple.
First the hack, using my own UILabel derived class:
#interface NavigationItemLabel : UILabel
- (void)setFrame:(CGRect)frame;
#end
#implementation NavigationItemLabel
- (void)setFrame:(CGRect)frame {
// Called by UINavigationBar layoutSubviews.
frame.origin.y -= self.font.descender;
}
#end
For some reason, frame.origin.y == -11, no matter what font I use.
Does anyone have any intuition as to why this is?
Adding my font's descender (custom font called Gabriola) seems to help. Without this hack, the text is aligned with the bottom of the descenders on the center of the navigation bar.
This doesn't work for all fonts.
Does anyone have a better solution?
Thanks.
If you are deploying to iOS 5+, you could check out the titleVerticalPositionAdjustmentForBarMetrics property the in the UINavigationBar documentation:
- (CGFloat)titleVerticalPositionAdjustmentForBarMetrics:(UIBarMetrics)barMetrics
Returns the title’s vertical position adjustment for given bar metrics.
Also, you should check out titleTextAttributes (also iOS5+), which you can use to set a custom font:
NSDictionary *attributes = #{
UITextAttributeFont: yourFont
};
[navBar setTitleTextAttributes:attributes];
If you're NOT on iOS5, I'd suggest wrapping the UILabel inside a UIView and setting your UIView as titleView instead (this allows you to further adjust the wrapped label's position by changing its frame).
If you have access to the WWDC 2012 videos (i.e. if you've got a developer account), I'd strongly recommend watching the talk on Advanced Appearance Customization on iOS (this stuff is included there).
Hope it helps somehow.
I had the same problem using Grotesque and there was a great SO solution shown by #kolyuchiy here. (It involves downloading the Apple Font Tool Suite command line utilities and adjusting the ascender attribute for your custom font).