I am developing an iPhone application for ios 7.1. The ViewController hierarchy is like "NavigationController -> UIViewController -> UIPageViewController -> UITableViewControllers". NavigationBar is hidden. Status bar is present. Everything is done programmatically. No storyboard/Xib is used.
In the UIPageViewController, I am creating a custom Title view (similar to the Navigation bar, but inside its own view). Hence the child controller's view (UITableView) should be pushed below this Title View. I have tried adding a constraint ("V:[TitleView]-0-[ChildView]"), after setting translatesAutoresizingMaskIntoConstraints of child view to NO. But this resulted in a blank screen (except for the title view). Changing frame of the child view etc and all did not have any effect.
Apart from setting the above flag and adding the constraint, I have not added/modified any auto layout/auto resize related settings. The application supports only the portrait mode (Home button down). There is not going to be any other dynamic layout change either. Appreciate if you could help in resolving this issue.
Following is the solution I ended up with as of now. Project was on hold for some time, and now being rewritten in Swift. Hence the below code is in swift.
//in the UIPageViewController
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
let scrollView = view.subviews[0] as UIView
scrollView.frame = CGRectMake(scrollView.frame.origin.x, 64, scrollView.frame.size.width, scrollView.frame.size.height - 64)
}
Basically I am moving and resizing the Page controller's default scroll view below my title view. I have to admit that I am not very happy with the solution. I feel that there must be some better alternative. (To make it safer, you can iterate the subviews to find the scroll view).
Look at the autoresize constraint from your page view controller and set it to false.
I think it's not the child which are autoresize but the pageviewcontroller frame.
Related
The alignment of our table is working well except of the top alignment of the top cell which bleeds into the "carrier area". What is required to address this?
We're using self sizing cells:
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 68.0
tableView.rowHeight = UITableViewAutomaticDimension
Overview of the current constraints:
Basically Apple doesn't want you to do what you're doing. Look at Apple's apps (Settings, Mail, etc.). You will never see a full-screen table view without a navigation bar at the top. So imitate that. Instead of fighting the framework, wrap your view controller in a UINavigationController and let the navigation bar push the top of the table view down for you automatically.
Normally when you use a navigation controller to wrap the view controller, TopLayoutGuide (and BottomLayoutGuide will be set for you and with "Adjust Scroll View Insets" that you can set in the storyboard file, it will automatically set contentInsets of the outermost scrollview for you to accommodate that. But since you don't use a navigation controller to wrap your view controller here, you have like three options.
1. Manually set the frame of the table view to offset for the status bar's height.
We just move the table view down 20 points and make it 20 points shorter. The ideal place is somewhere in your code we know it will be called every time the superview's bound is changed. One of them is in viewDidLayoutSubviews.
Try putting this code in your view controller's code.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.view.superview!.backgroundColor = UIColor.whiteColor()
let insets = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
self.view.frame = UIEdgeInsetsInsetRect(self.view.superview!.bounds, insets)
}
Please note that I have to set the background color of the superview's to white because the superview (which is likely to be UIWindow) might have no background color and it will make the top part appears black. And normally in the production code, you might want to check whether the superview's bound has really changed before setting the frame.
2. Use UIViewController and add UITableView as subview.
This way Interface Builder will allow you to set the constraints all you want.
3. Just wrap this with UINavigationController
And it will appear like most apps that have a navigation bar on the top. This might not be what you want. But I rarely see a table view without wrapping by a navigation controller.
Select your table view. In the bottom right side of your screen (left of where you drag the objects to the screen) you will see 4 small buttons. If you click on the 2nd to the right (a square with 2 lines to it's sides) you will see a small sub-menu saying Add new constraints. Below it you have a square with 4 values (top-right-bottom-left). Make sure the top one is 0 and then click the semi-transparent dotted red line. It should become solid red. Now just click the "Add constraints" button at the bottom and you are done.
This should be a very basic question, but I have tried a lot of things and it isn't working. :/
I have a single view application which consists of a single, full-screen custom view. I had my view class set on the main view of the view controller, but the status bar was always overlaid on my view.
Apple says to fix this, constrain your view to the top layout guide, but that requires I move my view to be a child of the main view. So I moved it, but now I can't set up constraints to simply make my view fill 100% of vertical and horizontal space.
I have tried doing it in code, using constraints, stacked views, anything I can find, but to no avail.
So, the hopefully simple question is, how can I make a single UIView child of the main view of a view controller size to fill the container and account for the status bar? The UIView is a custom class, so if code is needed I can do that.
I have tried overriding the intrinsic and size that fits methods, but they created terrible results.
You can do this programmatically:
let childView: UIViewCustom = UIViewCustom()
childView.frame = rootView.frame
childView.bounds = rootView.bounds
rootView.addSubview(childView)
Or via IB:
first select your childView, then click on the pin button in the low-right corner of XCode, disable Constrain to margins, then click on each red bar and set to zero the constrain. Finally click on Add 4 Constraints
Hope it helps.
try this:
0.Assume that you have a custom class just for View (not ViewController) named AAA.
in Main.storyboard, drag a "View" from Object Library to your ViewController. Call it ViewB.
2.set the viewB layout and constrains
3.select the viewB and go to its identify inspector(3rd small button on the right panel)
4.in the class section: write it as: AAA
Hope this will help you.
I have a UIPageViewController (parent) managing multiple UIViewControllers (children). Children VC only have 1 UIImageView with the the following constraints: 0 px to left and right, 0 px to Top layout guide, 20px to bottom layout guide
When I change page in Forward direction, it behaves correctly. When I change page in Backward direction, said UIImageView seems to cover the whole space (similar to what it would look like if it had no constraint) during the transition animation, and when the transition is done, it corrects it's position.
Long story short, when going flipping page backwards, the image appears bigger during animation, and then it changes to the correct size. Why is this happening?
PS: I created a boilerplate "Page based application" and it doesn't happen
Edit: My storyboard nest a couple of VC like this: TabBarController -> UINavigationController -> UIPageViewController. The VCs hosted by pageVC are added dynamically in code.
I already tried setting the UIImageView constraints to the parents and I noticed 2 things:
The top part of the image is being hidden by the navigation bar.
The problem persist
Any ideas?
Edit: 2
My NavigationController host a VC that pushes UIPageViewController (maybe this is not how it's supposed to be done?) , so I don't really "add" the UIPageViewController through code. I add it's children through code. Here's a SS
Moreover, the children are just a UIViewController with a UIImageView with 0 constraint to the container view (not the layout guide), so it covers the whole space.
The problem is the frame of the of UIPageViewController, when we instantiate it from the storyboard the view frame is equal to the screen frame (without the topLayoutGuide and bottomLayoutGuide) and also the childs view controller take the same frame...
So to fix that we have two solutions :
The first solution
Add the topLayoutGuide and the bottomLayoutGuide constraints to the imageView, but with this solution we get some problems with animation, because the frame is calculated only when the page is completely shown (you can find more details here : https://stackoverflow.com/a/29589531/2477632)
The second solution
1- Instantiate differently the MagazinePagesViewController : Create
MagazinePagesViewController with UIViewController super class (and
not UIPageViewController)
2- Add programmatically a pageViewController
let pageViewController = UIPageViewController(transitionStyle: UIPageViewControllerTransitionStyle.Scroll, navigationOrientation: UIPageViewControllerNavigationOrientation.Horizontal, options: nil)
pageViewController.view.frame = view.frame //add also some constraints if needed to support rotation
view.addSubview(pageViewController.view)
addChildViewController(pageViewController)
pageViewController.didMoveToParentViewController(self)
If needed I can upload the sample code with these two solutions.
Hope that helps
I have a View inside a ScrollView inside my main View
The problem is that my scrollView have a bad default contentOffset.
His value is (0, -64) in portrait
The Apple doc says
The default value is CGPointZero.
I put this code on my controller to temporary handle it :
dispatch_async(dispatch_get_main_queue(), {
self.scrollView.setContentOffset(CGPointZero, animated:false)
})
Why my contentOffset have not the good default value ?
It's probably an issue with the view insets.
On your XIB/Storyboard for your view controller, make sure to uncheck the Adjust Scroll View Insets
or in your code add self.automaticallyAdjustsScrollViewInsets = false
Swift 4.2+
scrollView.contentInsetAdjustmentBehavior = .never
I found the explanation on this website:
http://www.codelord.net/2013/10/18/adapting-scroll-views-to-ios-7/
Handling navigation bar on top of our scroll view
The iOS 7 view of course comes with the new look where scroll views go under the navigation bar for a nice effect. One can change the scroll view’s contentInset manually to cover for the portion of it that is being overlapped at the top, but doing so manually is tedious and not fun. I was very thrilled to discover handling it should come at no cost if my ViewController has automaticallyAdjustsScrollViewInsets set to YES.
This didn’t work for me out of the box since it turns out for the magic to happen the scroll view has to be the first subview of your ViewController’s UIView. I had to reorder my subviews and then the magic started rolling.
I have a composite structure of view controllers - parent view controller's view has a hole in it where I embed other view of another view controller.
I use addChildViewController and then add that child view to my view.
Now the tricky part - that view has UIScrollView and it refuses to scroll. I have made that UIScrollView in Xib, by embedding two other views in it.
I have checked frame and contentSize of that scrollView, and everything is normal, content size is big, frame is actual.
In viewDidLoad I use this:
self.scrollView.contentSize = CGSizeMake(3000, 3000);
I have tried setting delegate, userInteractionEnabled, scrollingEnabled but none of these helped. I have tried setting all superviews UserInteractionEnabled and such, but it didn't help too.
I have a feeling that it is a bug with Xcode, and I might just make scrollview in code, but this pisses me off, since I have huge hierarchy of labels and it will be hard to make them in code.
I use ios5 and no autolayout.
I tried changing background color to green and I can see the scrollview on screen, it is on correct place.
If you are using paging then use
self.scrollV.contentSize = CGSizeMake(self.scrollV.frame.size.width *kNumberOfPages, 220);
self.scrollV.showsHorizontalScrollIndicator = NO;
self.scrollV.showsVerticalScrollIndicator = NO;
self.scrollV.scrollsToTop = NO;
self.scrollV.delegate = self;
Here you can use number of pages to show.But before this please set delegate UIScrollViewDelegate of UIScroll view to that class. Please also check autolayout in your view too.
Hope this helps.