Full-screen UIImageView aligning to bottom - objective-c

With the following code:
UIImageView *largeImageView = [[UIImageView alloc] initWithImage:theImage];
[largeImageView setContentMode:UIViewContentModeScaleAspectFit];
largeImageView.frame = [[UIScreen mainScreen] applicationFrame];
[viewController.view addSubview:largeImageView];
viewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:viewController animated:YES];
I would expect the image to be at the top of the View, not the bottom. I double-checked the origin x and y, and they are 0,0.
Here is a screenshot: http://cl.ly/8F3J

Thanks to Tommy for providing some thinking out loud and debugging help, I figured out what I was doing wrong. I changed around the order of operations and added the imageview as a subview after I pushed the viewcontroller on the nav stack. This fixed the issue as my view controller had it's new view from the nav controller.

largeImageView is a subview of viewController.view, so its coordinates are relative to that of its superview. Probably you want something more like:
// the bounds of viewController.view contain its correct size, but
// have an origin of (0, 0)
largeImageView.frame = viewController.view.bounds;
[viewController.view addSubview:largeImageView];
What's probably happening at the minute is that you're getting a frame much larger than the view controller's view size, then the fact that UIViewContentModeScaleAspectFit will be adding some space at the top and bottom of the view as necessary (assuming your image is proportionally wider than the target view) is pushing the image off the bottom of the screen.

Related

Force Subview to fill parent

I have some subviews that I place inside each of my tab bar's view controllers. Right now I'm sizing it with a pixel count but it only works on the iPhone 4 and 4s and not the iPhone 5 because of the longer screen size. I could check for the device and then size it that way but I feel like there has to be an easier way to do this.
viewController1.view.frame = CGRectMake(0, 0, 320, 460);
I colored the subview yellow so it's easier to see.
You should NOT change frame of tabbar's content view controller's view. UITabBar takes itself care of sizing the child view controller's frame properly.
If you want to add subview to content view controller (controller under some tab) and make that view to always automatically resize with the controllers main view (self.view), you can use combination of superviews frame and autoresizing.
Example code (you can do this in - (void)viewDidLoad for example):
UIView *view = [[UIView alloc] initWithFrame:self.view.bounds];
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:view];
If you want to do this by setting frame than DO this:
[childView setFrame:childView.superview.bounds];
The master view in your view controller should already be the size of the usable space on the sceen. In general, if you want a view to be the same size as it's parent, you can use view.frame = view.superview.frame, though I doubt that would be a good idea to call on the view controller's view.

Can't move my UIScrollView

I have a content size 1000x10000 and it's center is on the center of the viewcontroller.
I want to push a button for it to turn pages. In the next code I've tried almost any number in the origin.x but nothing changes the scroll view.
I don't understand the math of it but when I set origin.x=300 and origin.y=100 the view will move up a bit but that's it.
CGRect frame=scroller.frame;
frame.origin.x=ANY NUMBER HERE;
frame.origin.y=0;
[scroller scrollRectToVisible:frame animated:YES];
How can I set it to move the view from right to left
Try this,
[scroller setContentOffset:CGPointMake(300, 0) animated:YES];
setContentOffset:animated:
Sets the offset from the content view’s origin that corresponds to the receiver’s origin.
You should be creating the UIScrollView's frame to the size of the UIViewController like so:
UIScrollView *scroller = [[UIScrollView alloc] initWithFrame:self.view.frame];
Then set the scrollers CONTENT VIEW to the 1000x10000 size like so:
scroller.contentSize = CGSizeMake(1000, 10000);
The contentSize is what makes a UIScrollview able to scroll, as long as the contentsize is larger than the scrollers frame.
If you want to make it scrollable, then contentSize has to be greater than frame.size, otherwise there isn't space to scroll.
Then ensure that scrollEnabled is set to YES (by default it is, so unless that you've changed it it's already set to YES).

How to programmaticaly add an UIActivityIndicatorView to a view on the bottom right corner

I'm trying to programmatically add and position an UIActivityIndicatorView to the bottom right corner of my main view. My app can rotate.
Right now in my viewDidLoad-method I have this code:
[super viewDidLoad];
UIActivityIndicatorView *iv = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[iv startAnimating];
int margin = 14;
iv.frame = CGRectMake(
self.view.frame.size.width - iv.frame.size.width - margin,
self.view.frame.size.height - iv.frame.size.height - margin,
iv.frame.size.width,
iv.frame.size.height );
iv.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
[self.view addSubview:iv];
When the app is starting in portrait, the activity-indicator is positioned correctly. As soon as I rotate the device (or start the app in landscape) the positioning of the activityindicator is wrong.
How can this be fixed?
You also need a flexible top margin, so that the view will slip to up or down as the height of the main view changes. Also, the parent view needs  to autoresizesSubviews set to YES (which is default YES, so you are probably ok).
distanceLabel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin|UIViewAutoresizingFlexibleTopMargin);
On your view controller, override the method shouldAutorotateToInterfaceOrientation and correct the position when orientation changes.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation;

How to make detail view scrollable in master detail app

I have only been working in iOS for a few months but I have been banging my head against the wall for hours and hours for something that seems like it should be pretty straightforward. I used the master detail template in Xcode for an iPad app. I want the detail portion to be scrollable to show content below what is visible in the frame, in either orientation. I have tried numerous combinations of adding scrollviews in the DetailViewController in viewWillAppear, viewDidLoad, loadView...and the best I can come up with is what looks like a scrollable view on the top layer as it does show scroll bars and shows me that I did the scrollView.contentSize correctly as I can pan around, but the actual view with the fields and stuff doesn't move and the fields are unable to be edited. Here is my viewDidAppear as it stands at the moment. As you can see in the NSLogs I am trying to understand the view stack. If I uncomment the line before the logs, I lose the scroll bars altogether.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 768, 1024)];
scrollView.contentSize = CGSizeMake(2048, 2048);
UIView *parentView = [[UIView alloc] init];
parentView = [[self view] superview];
[[parentView superview] addSubview:scrollView];
//[scrollView addSubview:[self view]];
NSLog(#"%#", [parentView superview]);
NSLog(#"%#", parentView);
NSLog(#"%#", [super view]);
NSLog(#"%#", [self view]);
[scrollView setDelegate:self];
}
I would sincerely appreciate any guidance or tips on how to properly implement UIScrollView for this scenario.
You should add the UIScrollView in IB. Be sure to move all of your existing views and controls to be subviews of the scroll view. And you'll have to link the scroll view to an IBOutlet so you can set the content size in your view controller.
Instead of trying to wrap a uiscrollview around your main view's superview (which you have incorrectly tried to take ownership of (it should be NULL anyways)), why not herd your UI elements into a full-sized subview and wrap the scrollview around that? It would be much much easier.
Your hierarchy would look like this:
Self.view -> ScrollView (with contentSize set) -> UIView containing elements that need to be scrolled -> various UI elements

How do you determine the size/frame of a custom UINavigationItem.titleView?

After creating a custom view and assigning it to the navigationItem.titleView property it is displayed like this
with the custom view filling the space between the two buttons. Therefore, the custom view is not centered on the navigation bar. How do I determine the frame of the view in the .titleView property? I want to center some text in the navigation bar, say under the time stamp.
If you really want to get titleView's frame (in your top-level view's coordinate space), you can do this:
[self.navBar layoutIfNeeded];
CGRect titleViewFrameInTopLevelViewSpace = [self.navigationItem.titleView
convertRect:self.navigationItem.titleView.bounds
toView:self.view];
You need to do layoutIfNeeded if you have just assigned titleView, because by default the navigation bar won't lay out its subviews until the next pass through the run loop.
That said, the titleView will be centered automatically, if it fits. I think you are setting the frame (or bounds) of your custom view too large. I tested this two ways:
I set up the titleView directly in the XIB. I simply dragged a View from the Object library onto the center of the navigation bar:
It sized the view to 128x33 automatically. The resize handles let me adjust the size. It stays centered until it overlaps the Categorize button. Then it shifts left.
I set the titleView property in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
customView.backgroundColor = [UIColor greenColor];
self.navItem.titleView = customView;
}
The result looks like this:
You could get the width of the leftBarButtonItem and the rightBarButtonItem after you've set them, and then use that to determine how to centre within the view you supply to titleView. That might do what you want?