Ilya Loshkarev loshkarev.i@gmail.com
SFEDU 2016
// Defines position of the view in it's parent
var frame: CGRect
// Defines bounding rectangle for view's content
var bounds: CGRect
// Array of all subviews contained in the view
var subview: [UIView]
UILabel | displays static text |
---|---|
UIImageView | displays an image or an animated sequence of images |
UIScrollView | lets the user choose between certain options |
UIButton | lets a user initiate behavior with a tap |
---|---|
UITextField | allows the user to input a single line of text |
UISwitch | lets the user turn an option on and off |
UISlider | enables users to interactively modify some adjustable value |
UIDatePicker | is used for selecting a specific date, time, or both |
- touchDown
- touchDownRepeat
- touchUpInside
- touchUpOutside
- valueChanged
- editingDidEnd
- allEvents
- ...
button.addTarget(self,
action: #selector(buttonTouch(sender:)),
for: .touchUpInside)
Target — the object whose method is called
Action — the method of the object that is called
// Initiate View
loadView()
// View has been Initiated
viewDidLoad()
// View State Transitions
viewWillAppear()
viewDidAppear()
viewWillDisappear()
viewDidDisappear()
// View Size Changes
viewWillTransition(to:with:)
// Presents a view controller in a primary context
show(_:sender:)
// Presents a view controller in a secondary (or detail) context
showDetailViewController(_:sender:)
// Presents a view controller in a secondary (or detail) context
present(_:animated:completion:)
// Dismisses the view controller that was presented modally by the view controller
dismiss(animated:completion:)
Provides easy access to different views in an app
Each view can be a start of separate view stack
A segue represents the transition from one scene
to another
Show | Push on top of main stack | |
---|---|---|
Show Detail | Push on top of detail stack | |
Present in Popover | Show in popover view | |
Present Modally | Show on top of current root view | |
Custom | Custom Segue |
// Allows to make changes to the controllers before segue is performed
func prepare(for: UIStoryboardSegue, sender: Any?)
// Performs segue with specific identifier
func performSegue(withIdentifier: String, sender: Any?)
// Determines if the specific segue should be performed
func shouldPerformSegue(withIdentifier: String, sender: Any?)
Each segue has an identifier to distinguish it in storyboard
Connects storyboard item to the code
@IBOutlet weak var myButton: UIButton!
Connects event handler to a control
@IBAction func buttonTouched(sender: UIButton) { }
Auto Layout provides a set of constraints
to describe position and size of a view
in relation to its surrondings
- Top
- Bottom
- Leading
- Trailing
- Width
- Height
- Center X
- Center Y
- Baseline
Every view has 9 layout attributes
// Remove automatic constraints
button.translatesAutoresizingMaskIntoConstraints = false
// Create new constraints
var constraints = [
// Only views in the same view heirarchy can be constrained
button.topAnchor.constraint(equalTo: inputLabel.bottomAnchor),
button.leadingAnchor.constraint(equalTo: view.leadingAnchor),
button.widthAnchor.constraint(equalTo: view.bounds.width,
multiplier: 1 / buttons.count)
]
// Activate the constraints
NSLayoutConstraint.activate(constraints)
Portrait | Landscape | |
---|---|---|
iPhone 7+ | Compact width, Regular height |
Regular width, Compact height |
Other iPhones | Compact width, Regular height |
Compact width, Compact height |
iPad | Regular width, Regular height |
Regular width, Regular height |
Constraints can be installed just for specific Size Class
An abstract interface for responding to and handling events
// Recieve touch
touchesBegan(_:with:)
touchesMoved(_:with:)
touchesEnded(_:with:)
// Recieve motion
motionBegan(_:with:)
motionEnded(_:with:)
// Physical button pressed
pressesBegan(_:with:)
pressesChanged(_:with:)
pressesEnded(_:with:)
// Reset recognition process
reset()
- UITapGestureRecognizer
- UISwipeGestureRecognizer
- UIPanGestureRecognizer
- UIPinchGestureRecognizer
- UIRotationGestureRecognizer
- UILongPressGestureRecognizer
let recognizer = UISwipeGestureRecognizer(target: self,
action: #selector(swipeGesture(sender:)))
recognizer.direction = .down
view.addGestureRecognizer(recognizer)
override func touchesEnded(_ touches: Set<UITouch>,
with event: UIEvent?) {
super.tochesEnded(touches, with: event)
if state == .possible && someCondition {
state = .recognized // gesture is recognized
} else {
state = .failed // recognition failed
}
override var canBecomeFirstResponder: Bool { return true }
override func viewDidAppear(_ animated: Bool){
self.becomeFirstResponder()
}
override func motionEnded(_ motion: UIEventSubtype,
with event: UIEvent?) {
if motion == UIEventSubtype.motionShake { doTheShake() }
}
override func viewDidLoad(){
super.viewDidLoad()
let buttonProxy = UIButton.appearence()
buttonProxy.backgroundColor = .red
}
UIAppearence — allows to set default properties of UIView subclass
Unreliable for code generated views
Every view has underlying Core Animation Layer
UIView
– defines a rectangular region on the screen and handles the drawing and touch events
CALayer
– manages graphical properties of the view and handles view-related animations
override func viewDidLoad(){
super.viewDidLoad()
myButton.backgroundColor = UIColor.blackColor()
myButton.tintColor = UIColor.whiteColor()
myButton.layer.cornerRadius = 6
}
Some basic properties of a view can be set in
the Interface Builder
class MyButton: UIButton {
func stylize(){
self.backgroundColor = UIColor.blackColor()
self.tintColor = UIColor.whiteColor()
self.layer.cornerRadius = 6
}
override init(frame: CGRect){
super.init(frame: frame)
stylize()
}
// ... required methods
}
You should get mixed results:
button will look the same in IB,
but look as expected in simulator
@IBDesignable
class MyButton: UIButton {
// The following is only executed in the IB
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
// IB tends to override some properties set in viewDidLoad ???
self.backgroundColor = UIColor.blackColor()
}
}
@IBDesignable
shows that class is suitable for instancing in
the Interface Builder
@IBDesignable
class MyButton: UIButton {
@IBInspectable var cornerRadius: CGFloat {
get{ return layer.cornerRadius }
set{ layer.cornerRadius = newValue }
}
}
@IBInspectable
allows property to be set from
the Interface Builder
@IBDesignable
class RoundButton: UIButton {
override func drawRect(rect: CGRect) {
var path = UIBezierPath(ovalInRect: rect)
// set fill color
bacgroundColor.setFill()
// fill previously defined path
path.fill()
}
}
All the drawing happens in the view's graphic context