autoresize of uiview - objective-c

I have a UIView in a UITabController.
And there is a UITableView in it.
When toggling in call status bar it doesn't do anything and the view is not automatically resized.
It assumes the right size based on whether the in call UIStatusBar was toggled when the app starts but if the UIStatusBar is toggled whilst the app is running nothing changes.
Another tab view with a UINavigationController seems to resize fine.
Here is the code
if ([indexPath indexAtPosition:0] == 0 || [indexPath indexAtPosition:0] == 1) {
if (!airportChooser) {
airportChooser = [[AirportChooserController alloc] init];
airportChooser.targetController = self;
airportChooser.view.autoresizesSubviews = YES;
airportChooser.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[airportChooser.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
}
airportChooser.target = [indexPath indexAtPosition:0];
[self.parentViewController.parentViewController.view addSubview:airportChooser.view];
self.parentViewController.parentViewController.view.autoresizesSubviews = YES;
self.parentViewController.parentViewController.view.contentMode = UIViewContentModeRedraw;
[self.parentViewController.parentViewController.view setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
airportChooser.view.contentMode = UIViewContentModeRedraw;
//[airportChooser open];
}

Did you set the resizing mask of the UIView correctly? You can set it in Interface Builder in the size tab, it's the red lines that you can click.
You can also set it in code using something like:
[view setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight];
Also make sure the superview has set autoresizesSubviews to YES.
You can find more information about this in the UIView documentation.

Whilst klaaspeiter's answer makes sense and in some cases may be the right answer
in my specific case it was because I was adding a sub view to a UINavigationController's view with addSubview instead of pushViewController:view animated:NO;

Related

Only show the rows in UITableView

I have a UITableView and for the life of me I can't hide the header and all the footer. I have tried multiple methods posted on here.
I want to hide the white space on top and bottom of the populated rows.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Disable Scrolling in TableView
self.tableView.scrollEnabled = NO;
//Get rid of unpopulated rows
self.tableView.tableFooterView = [[UIView alloc] init];
//Hide UITableViewHeader
self.tableView.tableHeaderView = [[UIView alloc] init];
//Populate Table with Test Data
[self testTableView];
}
It looks like your UITableView's layout frame is not getting properly adjusted. Since I am not sure if you are using autolayout constraints or autozingmask therefore please try adding following code to your view controller to force your table to size according to the screen.
- (void)viewDidLayoutSubviews {
self.tableView.frame = self.view.frame;
}
Just set the tableviewHeader to nil or if you want to hide section headers just return nil from viewForHeaderInSection and reload the tableData.

How to get rid of the space on the left side of a custom UINavigationItem with a UISearchBar

In my navigation bar, I have a magnifying glass icon that brings up a search bar. I'm not using a UISearchDisplayController, so I opted to build my own UINavigationItem and then push it over the standard UINavigationItem using pushNavigationItem.
The problem is that the UINavigationItem seems to be pushed around 8 pixels to the right. This causes the cancel button (with localized text 'Annuleren') to be really close to the edge of the screen.
I tried inspecting the self.mySearchBar.bounds at runtime, but the origin is 0,0. I've played around a bit with AutoLayout and programmatically added constraints, but I haven't been successful. I hope it's possible without AutoLayout.
This is my code:
- (IBAction)displaySearchBar:(id)sender {
if (!self.mySearchNavigationItem)
{
self.mySearchNavigationItem = [[UINavigationItem alloc] initWithTitle:#""];
self.mySearchNavigationItem.hidesBackButton = YES;
self.mySearchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
self.mySearchBar.showsCancelButton = YES;
self.mySearchBar.delegate = self;
[self.mySearchBar sizeToFit];
[self.mySearchBar setPlaceholder:#"Zoeken..."];
UIView *barWrapper = [[UIView alloc]initWithFrame:self.mySearchBar.bounds];
[barWrapper addSubview:self.mySearchBar];
self.mySearchNavigationItem.leftBarButtonItem = nil;
self.mySearchNavigationItem.backBarButtonItem = nil;
self.mySearchNavigationItem.titleView = barWrapper;
UIButton *cancelButton;
UIView *topView = self.mySearchBar.subviews[0];
for (UIView *subView in topView.subviews) {
if ([subView isKindOfClass:NSClassFromString(#"UINavigationButton")]) {
cancelButton = (UIButton*)subView;
}
}
if (cancelButton) {
[cancelButton setTitle:#"Annuleren" forState:UIControlStateNormal];
}
}
[self.navigationController.navigationBar pushNavigationItem:self.mySearchNavigationItem animated:YES];
NSTimeInterval delay;
if (self.tableView.contentOffset.y >1000) delay = 0.4;
else delay = 0.1;
[self performSelector:#selector(activateSearch) withObject:nil afterDelay:delay];
}
try:
self.navigationController.navigationBar.barTintColor = self.mySearchBar.barTintColor;
if that doesn't work, you can add an underlay view to the navigation controller that is the color you would like. this may be useful: Get the right color in iOS7 translucent navigation bar
After searching for many hours, I gave up and went for a dirty fix. I'll leave it open for a while, in case someone knows why my searchbar is moved 8 pixels to the right.
Right before showing the UINavigationItem, I move the whole UINavigationBar to x-coordinate -8.
self.navigationController.navigationBar.frame = CGRectMake(-8.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
[self.navigationController.navigationBar pushNavigationItem:self.mySearchNavigationItem animated:YES];
And then on the cancel button click, I move it back to x-coordinate 0.
- (IBAction)cancelSearchBar:(id)sender {
[self.navigationController.navigationBar popNavigationItemAnimated:YES];
self.navigationController.navigationBar.frame = CGRectMake(0.0, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
}

UITableView first rows are cut-off under top bar

I have a UITabBarController with two UITableViews, all were created in the storyboard.
The problem is that in the second tableview the first few lines of the table are under the top bar, this doesn't happens with the first tableview, even if I change the order of the views the first will work perfectly and the second will present the problem, so the one that was working perfectly now presents the same problem because is the second item of the tabbar controller.
I don't have much code to show because I didn't create the tableviews programatically.
Not sure exactly based on your description, but a couple possibilities come to mind:
Check your view controller attributes inspector in IB. Look for
"Extend Edges" option under View Controller, and uncheck "Under Top
Bars" if it is checked.
In ios7, there appears to be a behavior in UIScrollView and all
subclasses whereby the content inset and offset is automatically adjusted, sometimes not very well. You
can try disabling that either in code or IB (see link for
how: iOS 7 -- navigationController is setting the contentInset and ContentOffset of my UIScrollView)
For any newly created iOS >7.0 app I suggest you take a deeper look at autolayout. For all my old iOS 6 apps I solved it like this:
In your UITableViewController interface:
bool _hasStatusBar;
bool _hasStatusBarHeight;
UIView *_blendView;
In your UITableViewController implementation file:
-(void)viewWillAppear:(BOOL)animated{
_hasStatusBar = NO;
_blendView = nil;
[self.tableView reloadData];
}
-(void)viewWillDisappear:(BOOL)animated{
_hasStatusBar = NO;
_blendView = nil;
}
- (void) viewDidLayoutSubviews {
// WTF APPLE!?
if (!_hasStatusBar) {
int topBarOffset = 20;
_hasStatusBar = YES;
// Fix for iOS 7 overlaying status bar
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect viewBounds = self.view.bounds;
_blendView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, viewBounds.size.width, topBarOffset)];
[_blendView setBackgroundColor:COLOR_MAIN];
[_blendView setOpaque:YES];
[_blendView setAlpha:1.00];
UIView *whityMacWhite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, viewBounds.size.width, topBarOffset)];
[whityMacWhite setBackgroundColor:[UIColor whiteColor]];
[whityMacWhite setOpaque:NO];
[whityMacWhite setAlpha:0.80];
[_blendView addSubview:whityMacWhite];
[self.view.superview addSubview:_blendView];
}
}
}

UICollectionView Views Layer Priority

I'm seeing a very odd behavior with UICollectionViews.
Here is the scenario.
I have a UIViewController that has been pushed on to a UINavigationController stack.
The UIViewController view has nav bar and UICollectionView in grid layout. 3 cells wide by unlimited tall.
Just below extent of screen, I also have a UIToolbar hidden. The UIToolbar is on top of UICollectionView in layer hierarchy.
I then allow the user to put view in to "edit mode" and I animate UIToolbar on to the screen and covers bottom portion of UICollectionView. If user leaves "edit mode" I move UIToolbar back off screen.
While in "edit mode" I allow the user to multi select cells with check boxes that appear and uitoolbar has delete button.
Delete does the following:
- (void)deletePhotos:(id)sender {
if ([[self.selectedCells allKeys] count] > 0) {
[[DataManager instance] deletePhotosAtIndexes:[self.selectedCells allKeys]];
[self.selectedCells removeAllObjects];
[self.collectionview reloadData];
[self.collectionview performBatchUpdates:nil completion:nil];
}
}
// Data Manager method in singleton class:
- (void)deletePhotosAtIndexes:(NSArray *)indexes {
NSMutableIndexSet *indexesToDelete = [NSMutableIndexSet indexSet];
for (int i = 0; i < [indexes count]; i++) {
[indexesToDelete addIndex:[[indexes objectAtIndex:i] integerValue]];
NSString *filePath = [self.photosPath stringByAppendingPathComponent:[self.currentPhotos objectAtIndex:[[indexes objectAtIndex:i] integerValue]]];
NSString *thumbnailPath = [self.thumbPath stringByAppendingPathComponent:[self.currentPhotos objectAtIndex:[[indexes objectAtIndex:i] integerValue]]];
if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]) {
[[NSFileManager defaultManager] removeItemAtPath: filePath error:NULL];
[[NSFileManager defaultManager] removeItemAtPath: thumbnailPath error:NULL];
}
}
[self.currentPhotos removeObjectsAtIndexes:indexesToDelete];
}
The data manager contains photo objects and are used in cell creation like so.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"imageCell" forIndexPath:indexPath];
NSString *pngfile = [[[DataManager instance] thumbPath] stringByAppendingPathComponent:[[[DataManager instance] currentPhotos] objectAtIndex:indexPath.row]];
if ([[NSFileManager defaultManager] fileExistsAtPath:pngfile]) {
NSData *imageData = [NSData dataWithContentsOfFile:pngfile];
UIImage *img = [UIImage imageWithData:imageData];
[cell.imageView setImage:img];
}
if ([self.selectedCells objectForKey:[NSString stringWithFormat:#"%d", indexPath.row]] != nil) {
cell.checkbox.hidden = NO;
} else {
cell.checkbox.hidden = YES;
}
return cell;
}
So here is where I'm finding issues:
When deleting enough cells so that number of visible rows changes, UIToolbar is disappearing. In case of a full row of 3, if I only delete 1 or 2 items, the UIToolbar doesn't disappear. I am not doing any animation on the UIToolbar in delete method and only when hitting a Done button that ends edit mode. I've confirmed that this method isn't being called.
I've also confirmed that the UIToolbar isn't actually moving. If I add "self.collectionview removeFromSuperView" on hitting delete in cases where UIToolbar would normally disappear, the UIToolbar is exactly where expected on the screen. This gives me the impression the UICollectionView is somehow changing layer hierarchy in draw of parent view.
I've attempted trying to bringSubviewToFront for UIToolbar and sendSubviewToBack for collectionview and has no affect.
Re-iniating open toolbar causes uitoolbar to animate back in. Oddly, however, it seems to animate from below screen! This makes no sense unless the UICollectionView is somehow pushing the UIToolbar off the screen due after the point where I would be calling the removeFromSuperview call so I can't re-create.
One "solution" I have is to force the UIToolbar to come back in to position but without animation after a 0.01 second delay
[self performSelector:#selector(showToolbarNoAnimation) withObject:nil afterDelay:0.01];
This works.
Here is the question:
Any idea why UICollectionView causing this behavior to push UIToolbar offscreen after a full row is deleted? The hack works but doesn't explain the issue.
Thanks,
James
When you use auto layout, and your views are loaded from a storyboard (or xib), you can't set the frames of your views. Doing so may seem to work initially, but at some point auto layout will reset the view's frame based on the constraints, and you won't understand what happened, and then you'll post a question to stack overflow.
If you need to change the layout of a view, you need to update the view's constraints instead.
There is a constraint specifying the distance between the bottom edge of your toolbar and the bottom edge of its superview. Presumably that distance is -44 (where 44 is the height of the toolbar).
You need to connect that constraint to an outlet in your view controller. The outlet will have type NSLayoutConstraint *. Call it toolbarBottomEdgeConstraint.
When you want to animate the toolbar onto the screen, set constraint's constant to zero and call layoutIfNeeded in an animation block:
- (void)showToolbarAnimated {
[UIView animateWithDuration:0.25 animations:^{
self.toolbarBottomEdgeConstraint.constant = 0;
[self.toolbar layoutIfNeeded];
}];
}
To hide the toolbar, set the constraint's constant back to its original value:
- (void)hideToolbarAnimated {
[UIView animateWithDuration:0.25 animations:^{
self.toolbarBottomEdgeConstraint.constant = -toolbar.bounds.size.height;
[self.toolbar layoutIfNeeded];
}];
}

Activity indicator not in center of the subview (which is not same size as parentview)

I am trying to center a spinner in the middle of the page using the code below.
self.aSpinner.center = self.view.center;
However when when I run the program, the spinner does not seem to be in the center
Is there any way to fix this?
EDIT:
I found the problem. It's not that the spinner is not in the center, but instead the subview has different bounds than its superview.
I am doing something like this in my code:
self.navcon = [[UINavigationController alloc]init];
self.photoViewTable = [[PhotoTableViewController alloc]init];
self.loadingPage = [[LoadingPageViewController alloc]init];
[self.photoViewTable.view addSubview:loadingPage.view];
[navcon pushViewController:photoViewTable animated:NO];
[self.window addSubview:navcon.view];
How can I set the size of loadingPage view to be equal to the parent view?
[spinner setCenter:CGPointMake(kScreenWidth/2.0, kScreenHeight/2.0)];
Setting the center properties might not be enough. In case your frame is being resize i will also set the autoresize mask of the spinner view:
spinner.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
spinner.center = CGPointMake(CGRectGetWidth(self.view.bounds)/2, CGRectGetHeight(self.view.bounds)/2);
Try do it on ViewDidAppear, there is correct self.bounds of view
I don't check self.center.
self.aSpinner.center = CGPointMake(self.view.bounds.width/2.0, self.view.bounds.width/2.0)
Work correct!
Check self has view or self is view