Skip to content

Instantly share code, notes, and snippets.

@eonil
Last active May 1, 2020 16:46
Show Gist options
  • Save eonil/6e523bd220a581d82670 to your computer and use it in GitHub Desktop.
Save eonil/6e523bd220a581d82670 to your computer and use it in GitHub Desktop.
UIKit Note

UIKit Note

Autolayout

  • If you want self-sizing view by its subviews, just do not set its sizing constraint. Then it will become the smallest possible size that can contain subviews.

  • intrinsicContentSize is ONLY for leaf nodes that cannot infer its size by constraints. Do not use it for intermediate (branch) nodes. Also, invalidateIntrinsicContentSize: method exists for intrunsicContentSize. So do no use it for intermediate nodes.

  • contentHuggingPriorityForAxis and setContentCompressionResistancePriority are also for intrunsicContentSize. So do not use them for intermediate nodes.

  • NEVER use CGFloat.max. Autolayout does not support it, and will cause internal error state --- silent corruption. Or _NSLayoutConstraintNumberExceedsLimit exception will be thrown. (discovered in iOS 8.1, Xcode 6.x)

  • ALWAYS make them to be prepared for 0 × 0 sized. Otherwise, you will see so many of UIViewAlertForUnsatisfiableConstraints exceptions. Usually the easest fix for this is lowering priority to a value under 500, so the layout engine to compress them freely. (discovered in iOS 8.1, Xcode 6.x)

  • Priority constant symbols are missing in Swift side. Arrr...!

  • Priority 1000 (which is default) means the constraint must be always satisfied. If the constraint couldn't be satisfied, the program and layout will be crashed or broken.

  • Priority 750 will resist to compression by default, and priority 250 will be more likely to be compressed.

  • Some layout manager views (e.g.: UITableView) still use manual layout and autoresizing stuffs on layout. Then you MUST set translatesAutoresizingMaskIntoConstraints to true when supplying view to them. For example, any table headers/footer, section headers/footers and any cells must set it to true. Actually this is an explicit rule noted on auto-layout manual. (you should turn it on for views that you're not managing thier layout) I believe this rules are equally applied to UICollectionView or any other layout manager views, and or even AppKitt stuffs.

  • It is bad idea to make constraints with external views because the view at path can be changes at any time due to mutable nature, and constraint may go invalid silently. Use constraint ONLY when you can control all the elements yourself. If you have to, install assertions or preconditions heavily.

  • Some views does not fully support autolayout. (e.g.: UITableView). It is unclear that this is because of it is legacy or there's any other reasons. Any autolayout definitions for subviews simply will not work with these views. (iOS 8.x)

    • UITableViewController

    These views are confirmed to work well.

    • UIViewController
    • UICollectionViewController
  • Layout-guide means top of content. So in UITableView, it means top of first row. And it seems scrolling with rows. Before that, UITableview doesn't support autolayout well, so I am not sure whether it is working or not.

  • If you want to make sure the layout, don't forget to call some of these methods:

    • setNeedsUpdateConstraints
    • updateConstraintsIfNeeded
    • setNeedsLayout
    • layoutIfNeeded

UIScrollView (iOS 8.0+)

  • Scrolling doesn't stop by setting new contentSize. If the indicators are displayed, they will look like jumping.

UISearchController (iOS 8.0+)

It's buggy, and there's no fix or workaround. (iOS 8.1, Xcode 6.2) This is just buggy in every situations. Especially the screen is rotated. It breaks layout with status bar. This breaks with UITableView. Also breaks with UICollectionView. Both in same ways. Navigate one depth, rotate to landscape, and come back to the search screen, and rotate back to portrait. Ta-da~ It breaks! This breaks even in Apple made apps such as Mail. AddressBook performs some dark magic, so this does not break, but nobody really know how they did that. I don't think we can do same thing without Cocoa Touch source code. Should I try to disassembling...?

I don't know why and how to fix this. If you can, just don't use this at all. If you have to use this, don't embed in table-view or collection-view. Never works. If you have to, prevent UI rotation. Support only one orientation. Otherwise, you'll see insane bugs and any trial to get around it will just waste your time. I wasted 1 week on this. No more. That's enough. Oh please Apple guys. Do some TEST BEFORE you RELEASE a SDK product.

If you have to deal with this control, this might be final resort.

  • Place it into UInavigationItem.titleView. This is THE ONLY WORKING WAY WITH ROTATIONS!. And this also fits to Apple's new look trend. (See Yosemite's new Safari for example. A search bar is placed in title bar and there's no visible title anymore.)

  • Don't set it into UITableView.tableHeaderView. It will horribly breaks when you rotate the device. Sometimes it looks working, but fails again when you navigate in and out to a depper view-controller using navigation controller. Trust me (who is older version of you). It never work, and Apple is not willing to fix this. They're all hooked up on removing titles.

  • There's definesPresentationContext = true. You may want it.

  • There's hidesNavigationBarDuringPresentation property. You may want it.

  • UISearchDisplayController is deprecated and legacy. And, also have same issues. Yes, it also breaks on rotation.

Architecture

Child view controllers. Do not use them to abstract full-screeen layout stuffs. Especially, Apple provided preset view-controllers (e.g.: UIViewController) does not handle this situation very well, so does not work well. Use them only for fragmental views that you can have full control. Even for them, these child view controllers may cause several issues... The best way is just only using UIView and subclasses.

WWDC Video Links by Topics

Customizations

Here're official examples.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment