UISplitViewController with a UIImageView on the Top? - iphone

What I want is the normal UISplitViewController, except it's moved down about 100px down so that an image can be at the top.
I tried to put the following in the splitviewcontroller init:
[self.view setFrame:CGRectMake(0, 140, self.view.frame.size.width, self.view.frame.size.height)];
but that didn't do anything.
Can anyone help?

UISplitViewController is built to take all the screen real estate and not really let you do any sort of custom design, even something as trivial as modifying it's frame.
I suggest you take a look at MGSplitViewController if you want to a customizable UISplitViewController.
Also don't forget to modify the frame's height, so part of what your drawing isn't off screen (ex. CGRectMake(0, 140, self.view.frame.size.width, self.view.frame.size.height*-140*)];).

Remy's advice is excellent here. Apple really went out of their way to prevent us from customizing UISplitViewController. MGSplitViewController is a good alternative. The only thing I'd add is that the init method is generally not the best place to adjust your view's frame, as UIKit tends to resize your view controller's view prior to display. A better place to adjust the frame is in viewWillAppear:.

Related

Navigation bar in UINavigationController too short

I'm putting together an app where some of the views are in regular UIViewControllers and use their own UINavigationBar, whereas others will be part of a navigation hierarchy inside a UINavigationController and make use of its UINavigationBar instead.
The problem is that the actual UINavigationBars that I'm seeing are different in these two cases. The ones in that use a UINavigationController's navigation bar seem unnaturally short. Here are some pictures, showing what I see in Interface Builder versus what I see at runtime.
I can't figure out what I'm doing wrong here. Why are the navigation bars different heights? How can I make them the same?
I truly believe you are mixing up two different features. UINaviationbar and UIToolbar. Here is apple's human guidelines. Look at the top of the document for Navigation Bar
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/mobilehig/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW41
I will try to see if I can find a document on their dimensions. Here is one. I am sure there are better ones available
http://www.idev101.com/code/User_Interface/sizes.html
Figured out what was going on here. UINavigationController resizes the navigation bar in portrait orientation automatically, and as far as I can tell, there is no built-in way to prevent this from happening. However, with the help of this post (How to prevent autoresizing UINavigationBar on Landscape), I was able to get it working the way I wanted. My code was slightly different from the code in the linked post. I used:
#implementation UINavigationBar (CustomHeight)
- (CGSize)sizeThatFits:(CGSize)size
{
// Need to know the width of the window
CGRect bounds = self.window.bounds;
// Sometimes height and width are turned around. Take the largest of height and width as the real width.
int width = (bounds.size.width > bounds.size.height) ? bounds.size.width : bounds.size.height;
// Make sure that the
CGSize newSize = CGSizeMake(width, 44);
return newSize;
}
I'm not sure if there's a better way to get the true width - the above is clunky but works for me since my app only runs in landscape. My bigger concern is that Apple says in its UINavigationBar documentation that you shouldn't directly adjust the frame. But I guess I'm not directly doing that; presumably internal drawing methods will call this method and do their thing.
Anyway, this works for me. Hope it helps someone else.

what is the similar of linear layout in ios

I have many components in my view controller, and I want to combine them in a single object to scroll them together, what is the procedure to do it (like linearlayout in android) but I need it in IOS.
iOS9 introduced something similar to LinearLayout: UiStackView
See this video from WWDC 2015: https://developer.apple.com/videos/wwdc/2015/?id=218
Apple not provide linear container
but you can use XHFLinearView at github
Usage Example:
XHFLinearView *linearView=[[XHFLinearView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:linearView];
//init linear view content views
[linearView.itemSource addObject:XHFLinearViewUnitMake(someView, XHFMarginMake(0, 0, 0, 0))];
//force layout linear view
[linearView needLayout];
//insert a view with animation
[linearView insertItem:someView margin:XHFMarginMake(0, 0, 0, 0) atIndex:0 withAnimation:XHFLinearItemAnimationFade];
//replace a view with animation
[linearView replaceItem:someView withNewItem:newView withAnimation:XHFLinearItemAnimationFade];
//resize a view with animation
someView.frame=xxx;
[linearView needLayoutForItem:someView];
//remove a view with animation
[linearView removeItemByIndex:0 withAnimation:XHFLinearItemAnimationFade];
LayoutManager
First of all, what you're looking for is a declarative API for layouts. I guess a lot of people that comming from other languages/platforms miss that. iOS just has some other approaches like layout constraints or autoresizing. However this does not fit all the use cases.
Layout libraries
I would suggest to take a look into some libraries existing at CocoaPods. Its easy to install and kick off with it.
I'd like to mention CSLinearLayoutView which is quite easy. Even I am maintainer of a smaller project MKLayoutLibrary which is available via CocoaPods as well. Thats a more compressive one which also provides a linear-, stack- and a simple flow-layout.
Clean solution
However, if you really want to go very deeply into the topic of layouts I recommend playing with UICollectionView and its layout customisation possibilities.
Consider that declarative solutions does not work for a huge amount of items or endless scrolling layouts. If you want to do so, take a further look into UICollectionView custom layouts.
I just wrote a widget called AutoLinearLayoutView which can be checked out from Github.
It's totally based on Auto-layout and supporting iOS 7+. According to your requirement, the example project perfectly demonstrates a dozen of widgets being wrapped by linear layout view, and the linear layout view being placed in UIScrollView.
Linear Layout in Android = Stack View in iOS
Android:
orientation: Horizontal, Vertical
iOS:
Horizontal Stack View, Vertical Stack View in iOS
More:
Recycler View in Android = Table View in iOS
There is no such layout available in iOS. Each component you add on the view will be displayed based on it's frame (not in sequential manner).
For doing this stuff you can use UIScrollView.
Check this tutorial How to use UIScrollView
You'll likely have to do something a bit more manual with iOS. You can add all your views to a UIScrollView, however you'll have to set the contentSize of the UIScrollView appropriately. Essentially, for N items, the scroll view width will be:
scrollView.contentSize = CGSizeMake(N * itemWidth + (N - 1) * itemPadding, itemHeight);
Then, you'll need to set the frame of each UIView so that its x-coordinate is appropriate, and add it to the UIScrollView:
for (int i = 0; i < views.count; i++) {
UIView *view = [views objectAtIndex:i];
view.frame = CGRectMake(i * itemWidth + i * itemPadding,
view.frame.origin.y,
view.frame.size.width,
view.frame.size.height);
[scrollView addSubview:view];
}
If you want something more complicated than a simple linear layout, have a look at UICollectionView.
Every component as uiview in ios. so you can put every components into UIView like
[containerView addSubView:YourComponent1];
[containerView addSubView:YourComponent2];
[containerView addSubView:YourComponent3];
then you can add this into your UIScrollView

UIViewController frame

I've got the following setup.
A pagingScrollViewController with a UIScrollView as it's view (self.view = scrollView).
In that scrollView I add the view of a rootViewController as subview.
The view of the rootViewController is an UIView on which I add one or the other view (depending on internal logic).
The UIScrollView is initialized with a frame equal to the applicationFrame, so 0, 20, 320 , 460. Which is fine because of the statusbar on top.
The problem comes when adding the rootViewController's view to the scrollview. In the creation process of the rootViewController it's view is setup in -loadView which is still commented out in my case. So the standard appel loadView is processed.
It gives me a view which also has a frame of 0, 20, 320, 460. Which is not as I would like to see it as now the View of the rootViewController is 40 pixels removed from the top of the actual iphone screen.
Now, this is of course easily fixed by manually setting the rootViewControllers view in -loadView or assigning it a frame where the y is set to 0 in -viewDidLoad;
But I cannot imaging that that is the way apple intended this to be done. I'm not using Interface builder, so maybe that's the problem, apple intends me to use IB, but im stubborn on that subject :)
Am I using viewControllers the wrong way? This seemed a nice way to split the logic of the scrollView away from the logic of the other view's.
What would be the correct way to add the view of a second UIViewController to the view of a first UIViewController. In which the first viewController.view receives a frame of 0, 20 , 320, 460. And de second controller.view a frame of 0, 0, 320, 460 (so basically the bounds of the first controller.view)
There's a lot of use of the word controller and view in there, hope the question is clear though.
To answer my own question...
Ravin was right.
After reading up on the loadView method and apple's view controller programming guide I've come to the conclusion that this is the default behavior of the system. If you want anything else, override -loadView and do it yourself. Actually apple states that if you don't use an NIB, you SHOULD override -loadView to create at least a basic simple view.

Why do I have to reposition this UIView by an arbitrary amount?

I am building an application that must add an overlay view once a scrollview is done zooming. I was having problems adding the overlay to the scrollview itself and keeping the position consistent, due to what I assume is the scrollview not being done zooming...no biggie...so I decided to add the overlay to the sharedApplication's keyWindow.
Now, the application is in landscape orientation, and I have to do a transform on the overlay to get it to orient properly...this is fine. The issue arises in having to reposition the overlay by this seemingly arbitrary amount to get it centered...I dislike doing things ad hoc like this, so I thought I'd ask if anyone has run into something like this, and why the view has to be repositioned by this strange offset. Any insight would be great.
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI/2);
tempOverlay.view.transform = transform;
// Repositions and resizes the view.
CGRect contentRect = CGRectMake(-107, -80, 480, 320); //where does this offset come from?!?
tempOverlay.view.bounds = contentRect;
[[[UIApplication sharedApplication] keyWindow] addSubview:tempOverlay.view];
I was going to post this as a comment instead of an answer originally, but I'll just go for the answer route instead, even though I don't think there's really enough information to go on here. The following assumes that you have a fairly standard iOS application, aside from this overlay oddity where you're attaching the view to the keyWindow.
First, don't attach add your overlay view to the keyWindow. Instead, define some method on your root view controller which requests the overlay be displayed. Then in your root view controller code, add the overlay view to the controller's view above everything else.
Then, don't apply the transform since it will no longer be necessary to rotate your view.
At the time you create your view, set it's frame to be the bounds of the root controller's view. Also set it to have a flexible width and height via the autoresizingMask of UIView. Then assuming your root UIView has it's autoresizesSubview property set to YES, your overlay view will be nicely resized to match the size of the root view as it changes orientation.
If after all this the position of the contents of your overlay UIView is incorrect then I suspect the problem is within the contents of that UIView and has nothing to do with the need for any magic numbers in your frame/bounds.
NOTE: I haven't actually tried the above and am not 100% confident that in general your root UIView will enjoy having this extra overlay UIView thrown on top of it, on the other hand, it might remain blissfully unaware of it and everything will Just Work. Either way, to me it feels a lot less 'ad hoc' than what you're currently trying to do.

iPhone. How to get the rect of parent view?

My application creates two views:
topView (CGRect = 0,0, 320,60)
bottomView (CGRect = 0,60, 320,480)
Bottom view creates UITabBarController with UIViewControllers:
ListViewController
etc...
ListViewController has own views that are created in viewDidLoad method:
background = [[UIImageView alloc] initWithFrame: rect ];
So my question is how to get the bottomView rect inside ListViewController?
I want to layout all controller views without intersection with topView.
Thank you.
Might I suggest you read the HIG. Spend a lot of time there as it will answer many design questions that your question shows you don't yet grasp. If you're not able to lay things out with standard controls and positions, you're probably going about it the wrong way.
That being said, your question in the content of your post seems to diverge from the title. If you simply want the parent view's rectangle, use:
CGRect parentRect = [[[self view] superview] frame];
in your view controller.
And when you say ListViewController, is this a view controller you created yourself, one you got from a library somewhere, or do you mean UITableViewController?
I suggest you don't layout your controls with code if you can use Interface Builder instead. That's not always possible, but it's a good practice to use IB when it is.