cs193p – Lecture #5 – Objective-C Compatibility, Property List, Views

cs193p - Lecture #5 - Objective-C Compatibility, Property List, Views

Please note, this blog entry is from a previous course. You might want to check out the current one.

Objective-C Compatibility

Lecture #5 starts with theory on how Swift was built to be compatible with Objective-C and thus provides numerous seamless bridging methods:

  • NSString bridges to String
  • NSArray bridges to Array<AnyObject>
  • NSDictionary bridges to Dictionary<NSObject, AnyObject>
  • Int, Float, Double, Bool bridge to NSNumer – but not the other way around – use instead intValue, floatValue, doubleValue and boolValue

Additionally, it is possible to implicitly cast using as.

Property List

Property lists are collection of AnyObjects.

NSUserDefaults are a way to store property lists persistently between launchings.

Get the defaults:

[swift]NSUserDefaults.standardUserDefaults()[/swift]

Store and retrieve property lists:

[swift]
setObject(AnyObject, forKey: String)
objectForKey(String) -&gt; AnyObject?
arrayForKey(String) -&gt; Array&lt;AnyObject&gt;?
setDouble(Double, forKey: String)
doubleForKey(String) -&gt; Double
[/swift]

Though changes are saved automatically, it can be forced:

[swift]defaults.synchronize()[/swift]

A short demo shows how to use property lists in the calculator app.

Views

UIViews are rectangular areas with a coordinate system for drawing and handling touch events. They are structured hierachically having a superview and subviews and a UIWindow at the very top.

Views most often are created using story board, but also in code:

[swift]
addSubview(aView: UIView)
removeFromSuperview()
[/swift]

Thus it has two different initializers which might have to do the exact same setup:

[swift]
func setup() { … }
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coderaDecoder:NSCoder) {
super.init(coder: aDecoder)
setup()
}
[/swift]

Additionally awakeFromNib is called when a view is generated via a storyboard.

Views use special data structures to define values, points, sizes and rectangles:

[swift]
typealias CGPoint = Double
struct CGPoint {
var x: CGFloat
var y: CGFloat
}
struct CGSize {
var width: CGFloat
var height: CGFloat
}
struct CGRect {
var origin: CGPoint
var size: CGSize
}
[/swift]

… with various convenience properties and functions:

[swift]
var minX: CGFloat
var midY: CGFloat
intersects(CGRect) -&gt; Bool
intersect(CGRect)
contains(CGPoint) -&gt;Bool
[/swift]

The origin of the coordinate system is in the upper left corner. Its units are points with a varying number of pixels (contentScaleFactor) depending on the used device.

frame defines the view in the super view, the view itself is defined by its bounds.

Custom Views

drawRect(regionThatNeedsToBeDrawn: CGRect) is called to draw custom views. To trigger – and indirectly call drawRect:

[swift]
setNeedsDisplay()
setNeedsDisplayInRect(regionThatNeedsToBeRedrawn: CGRect)
[/swift]

UIBezierPath are used to create shapes, e.g.:

[swift]
let path = UIBezierPath()
path.moveToPoint(CGPoint(80, 50))
path.addLineToPoint(CGPoint(140, 150))
path.addLineToPoint(CGPoint(10, 150))
path.closePath()
UIColor.greenColor().setFill()
UIColor.redColor().setStroke()
path.linewidth = 3.0
path.fill()
path.stroke()

let roundRect = UIBezierPath(roundedRect: aCGRect, cornerRadius: aCGFloat)
let oval = UIBezierPath(ovalInRect: aCGRect)
[/swift]

… or clip a view using addClip(), or for hit detection:

[swift]func containsPoint(CGPoint) -&gt; Bool[/swift]

Colors are handled using UIColor which even allows transparency using alpha values (don’t forget to set opaque to false).

Setting the hidden property of a view to true removes the view and its sub views completely from the screen.

To draw text use (mutable) attributed strings:

[swift]
let text = NSAttributedString(&quot;hello&quot;)
text.drawAtPoint(aCGPoint)
let textSize: CGSize = text.size
[/swift]

… and define the attributes of parts of mutable attributed string using dictionaries and ranges:

[swift]
func setAttributes(attributes: Dictionary, range: NSRange)
func addAttributes(attributes: Dictionary, range: NSRange)

NSForegroundColorAttributeName : UIColor
NSStrokeWidthAttributeName : CGFloat
NSFontAttributeName : UIFont
[/swift]

Concerning fonts it is best practice to use the ones defined in the user settings:

[swift]
class func preferredFontForTextStyle(UIFontTextStyle) -&gt; UIFont

UIFontTextStyle.Headline
UIFontTextStyle.Body
UIFontTextStyle.Footnote
[/swift]

… for standard objects like buttons the system fonts:

[swift]
class func systemFontOfSize(pointSize: CGFloat) -&gt; UIFont class func boldSystemFontOfSize(pointSize: CGFloat) -&gt; UIFont
[/swift]

Images can be drawn form the bundle or image assets, e.g.:

[swift]
let image: UIImage? = UIImage(named: &quot;foo&quot;)
image.drawAtPoint(aCGPoint)
image.drawInRect(aCGRect)
image.drawAsPatternInRect(aCGRect)
[/swift]

… or from file sources, e.g.:

[swift]
let image: UIImage? = UIImage(contentsOfFile: aString)
let image: UIImage? = UIImage(data: anNSData)
[/swift]

… or you can create them using core graphics (see UIGraphicsBeginImageContext).

UIViewContentMode defines what should happen when the bounds of a view changes. It could just been placed somewhere – .Left/.Right/.Top/.Bottom/.TopRight/.TopLeft/.BottomRight/.BottomLeft/.Center – scaled – .ScaleToFill/.ScaleAspectFill/.ScaleAspectFit – or redrawn – .Redraw.

The demo at the end of the lecture shows parts of the just learned theory.

The lecture and its slides are available via iTunes named “5. Objective-C Compatibility, Property List, Views”. The code for the calculator demo is available on GitHub. The code for the happiness demo is available on GitHub and Stanford.

Facebooktwittergoogle_plusredditpinterestlinkedintumblrmailFacebooktwittergoogle_plusredditpinterestlinkedintumblrmail

Leave a Reply

Your email address will not be published. Required fields are marked *