Category Archives: Uncategorized

UIStackView programmatically

demo

This project demonstrates how to:

– Create a UIStackView
– add uiviews to it
– add constraints to the uiviews
– make each uiview appear and disappear

stackview_row_result

http://angelolloqui.com/blog/36-Oddities-of-UIStackView
https://developer.apple.com/documentation/uikit/uiview/1622572-translatesautoresizingmaskintoco

Creating a constraint

Say you want to create a constraint. That constraints sits on constraint creation conveniences such as heightAnchor, widthAnchor, topAnchor, leftAnchor, etc. Any property that you can create a constraint on, that property will have an anchor you can access, and thus, create constraints from.

In our case, we want to to set a constraint to our height. Thus there is a heightAnchor. Access that property to create a constraint.

translatesAutoresizingMaskIntoConstraints

From the doc: If you want to use Auto Layout to dynamically calculate the size and position of your view, you must set this property to false, and then provide a non ambiguous, nonconflicting set of constraints for the view.

By default, the property is set to true for any view you programmatically create.

If you add views in Interface Builder, the system automatically sets this property to false.

Resolving Constraint conflicts using priority

Thus, later on we’ll be hiding our viewA. However there is a constraint on viewA that says its height has to be 120, as stated earlier. In this case, we’ll get a constraint conflict in the log console, because setting aView’s isHidden to true, makes its height to 0. This is a constraint conflict with 120.

Thus, in order to fix this, we need to lower the priority of our 120 height constraint so that when viewA’s height changes to 0 (due to it being hidden), it will see that the 120 height constraint’s priority is lower. This is because any new height constraints has a default priority of 1000. Since 120 has a lower priority, then the constraints engine will allow 0 (which defaults to highest priority of 1000) to be valid.

Full Source

Static methods vs class methods

https://stackoverflow.com/questions/29636633/static-vs-class-functions-variables-in-swift-classes

static and class both associate a method with a class, rather than an instance of a class.

The difference is that subclasses can override class methods; they cannot override static methods.

cannot_override_static_method

Cannot override final functions

cannot_override_final

Finally, you can finalize your override like so:

where to remove observer in swift

https://stackoverflow.com/questions/28689989/where-to-remove-observer-for-nsnotification-in-swift/40339926#40339926
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

Swift automatically deallocates your instances when they are no longer needed, to free up resources. Deinitializers are called automatically, just before instance deallocation takes place. You are not allowed to call a deinitializer yourself.

deinitializion in class hierarchy

Superclass deinitializers are inherited by their subclasses, and the superclass deinitializer (parent) is called automatically at the end of a subclass deinitializer (child) implementation. Hence, the lowest level (youngest kids) subclass calls their deinit. Then their parents. Then the parent’s parents…and so on.

Also, superclass deinitializers are always called, even if a subclass does not provide its own deinitializer.

As of iOS 9

As of iOS 9 (and OS X 10.11), you don’t need to remove observers yourself, if you’re not using block based observers though.

The system will do it for you, since it uses zeroing-weak references for observers, where it can.

In detail:
https://useyourloaf.com/blog/unregistering-nsnotificationcenter-observers-in-ios-9/

Using iOS 9 or later the Foundation framework release notes contain some good news:

In OS X 10.11 and iOS 9.0 NSNotificationCenter and NSDistributedNotificationCenter will no longer send notifications to registered observers that may be deallocated.
The notification center now keeps a zeroing reference to the observer:

If the observer is able to be stored as a zeroing-weak reference the underlying storage will store the observer as a zeroing weak reference, alternatively if the object cannot be stored weakly (i.e. it has a custom retain/release mechanism that would prevent the runtime from being able to store the object weakly) it will store the object as a non-weak zeroing reference.
So the next time the notification center wants to send a notification to the observer it can detect that it no longer exists and remove the observer for us:

This means that observers are not required to un-register in their deallocation method. The next notification that would be routed to that observer will detect the zeroed reference and automatically un-register the observer.

Note that this does not apply if you are using a block based observer:

Block based observers via the -[NSNotificationCenter addObserverForName:object:queue:usingBlock] method still need to be un-registered when no longer in use since the system still holds a strong reference to these observers.

AutoLayout, constraints, with xib/storyboards

A Beginner’s Guide to Auto Layout with Xcode 8


auto-constraints

Why Auto Layouts?

Say we put a label in the middle of our xib with “hello world”. If you run it in on different iPhone devices, the label will appear in different positions. This is because each device is a different size.

If we were to put something at the “middle” of an iPhone SE, it will look much different on a much larger iPhone 7S. In fact, it uses points straight up. So “middle” on iPhone SE may be (120, 260). When you run it on the iPhone 7S, the label will be at (120, 260), which is obviously not the middle of the iPhone 7S device. It will appear on the upper left region of the 7S screen.

Same concept when the device switches from portrait to landscape. Even though the device rotates, the label stays same as coordinate (120, 260)

Hence, auto layout is a constraint-based layout system. It allows developers to create an adaptive UI that responds appropriately to changes in screen size and device orientation.

Using Auto Layout to Center our label

Each button has its own function:

Align – Create alignment constraints, such as aligning the left edges of two views.
Pin – Create spacing constraints, such as defining the width of a UI control.
Issues – Resolve layout issues.
Stack – Embed views into a stack view. Stack view is a new feature since Xcode 7. We will further discuss about it in the next chapter.

center horizontally and center vertically. Both constraints are with respect to the view.

To create the constraints, we will use the Align function. First, select the button in Interface Builder and then click the Align icon in the layout bar. In the pop-over menu, check both “Horizontal in container” and “Vertically in container” options. Then click the “Add 2 Constraints” button.

add-vertical-horizontal-constraint

Now run the app in different device sizes, and you’ll see that the label should be centered in all of them.

Resolving Layout Constraint Issues

The layout constraints that we have just set are perfect. But that is not always the case. Xcode is intelligent enough to detect any constraint issues.

Try to drag the Hello World button to the lower-left part of the screen. Xcode immediately detects some layout issues and the corresponding constraint lines turns orange that indicates a misplaced item.

constraint_mishap

When there is any layout issue, the Document Outline view displays a disclosure arrow (red/orange). Now click the disclosure arrow to see a list of the issues. Interface Builder is smart enough to resolve the layout issues for us. Click the indicator icon next to the issue and a pop-over shows you a number of solutions. In this case, select the “Update Frame” option and click “Fix Misplacement” button. The button will then be moved to the center of the view.

xib-disclosure-arrow

Then, simply choose update the frame for xCode to resolve the problem for you.

list-issues

Alternative way to view Storyboard

You can also add more devices to preview:

add_more_devices

Add a label to the bottom right hand corner.

If you opened the preview assistant again, you should see the UI change immediately. Note that without defining any layout constraints for the label, you are not able to display the label on all iPhone devices.

adding-label-to-alternative-xib-view

The label is located 0 points away from the right margin of the view and 20 points away from the bottom of the view.

This is much better. When you describe the position of an item precisely, you can easily come up with the layout constraints. Here, the constraints of the label are:

The label is 0 points away from the right margin of the view.
The label is 20 points away from the bottom of the view.

In auto layout, we refer this kind of constraints as spacing constraints. To create these spacing constraints, you can use the Pin button of the layout button.

create-pin-constraints

Once you added the two constraints, all constraint lines should be in solid blue. When you preview the UI or run the app in simulator, the label should display properly on all screen sizes, and even in landscape mode.

constraints-landscape

?? in swift

https://stackoverflow.com/questions/30837085/whats-the-purpose-of-double-question-mark-in-swift
https://stackoverflow.com/questions/30772063/operator-in-swift
http://kayley.name/2016/02/swifts-nil-coalescing-operator-aka-the-operator-or-double-question-mark-operator.html
http://laurencaponong.com/double-question-marks-in-swift/

It is called nil coalescing operator. If highs is not nil than it is unwrapped and the value returned. If it is nil then “” returned. It is a way to give a default value when an optional is nil.

Technically, it can be understood as:

More Examples