EEC-492/693/793 iPhone Application Development Lecture 7 Wenbing Zhao & Nigamanth Sridhar 12/24/2018 EEC492/693/793 - iPhone Application Development
Outline More in-depth Objective-C A primer on coordinate system Memory management (and property) revisited The self keyword A primer on coordinate system Autorotation and autosizing Assignments: Build autosize 1, autosize 2, and swap apps Build a calculator app Objective-C part is shamelessly taken from Stanford CS193P winter 2010 lecture 3 12/24/2018 12/24/2018 EEC492/693/793 - iPhone Application Development EEC492/693/793 - iPhone Application Development 2
Memory Management Revisited What is going to happy if you were to run the code below (assuming other parts are implemented perfectly? // in foo.h @interface FooViewController : UITableViewController { NSArray *stuff; } @property (nonatomic, retain) NSArray *stuff; // in foo.m @synthesize stuff; - (void)viewDidLoad { NSArray *arr = [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2", @"Lorem", @"Ipsum", nil]; stuff = arr; [arr release]; } Code example and explanation taken from: http://stackoverflow.com/questions/1295702/setting-an-objective-c-class-property-without-using-a-self-reference 12/24/2018 EEC492/693/793 - iPhone Application Development
Memory Management Revisited How about this piece of code? // in foo.h @interface FooViewController : UITableViewController { NSArray *stuff; } @property (nonatomic, retain) NSArray *stuff; // in foo.m @synthesize stuff; - (void)viewDidLoad { NSArray *arr = [[NSArray alloc] initWithObjects:@"", @"Item 1", @"Item 2", @"Lorem", @"Ipsum", nil]; self.stuff = arr; [arr release]; } 12/24/2018 EEC492/693/793 - iPhone Application Development
Memory Management Revisited First version would crash as soon as the app is started, while the second version would work just fine The difference? Whether or not “self” is used: self.stuff = arr; This is quite puzzling. Shouldn’t we be able to access the class instance variable directly? Yes, we do. We can certainly manipulate instance variables within the class without having to use: self. What is the problem then? 12/24/2018 EEC492/693/793 - iPhone Application Development
Memory Management Revisited The problem is related to memory management Why version 1 crashed? stuff = arr; this assignment does not retain the array (arr) (aside from the implicit retain via alloc+init) When the next statement is executed: [arr release]; the retain count of the array (arr) drops to 0, and therefore, it is deallocated => stuff would point to nothing, which caused the crash Why version 2 works? self.stuff = arr; in this assignment, we are actually calling the setter of the property, which would increase the retain count by 1 due to the property declaration @property (nonatomic, retain) NSArray *stuff; 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development Property Delaration @property (nonatomic, retain) NSArray *stuff; retain means that the retain count (for the property) will be increased after the assignment self.stuff = arr; // stuff’s retain count will be increased by 1 Furthermore, the previous object (which stuff pointed to) is sent a release message This is why we can do this in viewDidUnload: self.nameField = nil; However, the release message is sent to instance variables directly un dealloc: method [nameField release]; 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development The self Keyword self is to be used within a method definition to refer to the object that performs the method You normally send a message to self However, the dot notation for declared properties (introduced in Objective-C 2.0) added confusion, especially for C++/Java programmers What does self.stuff mean? self.stuff = arr; // equivalent to [self setStuff: arr]; arr = self.stuff; // equivalent to arr = [self stuff]; 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development Coordinates CGFloat Just a floating point number CGPoint C struct with two CGFloats in it: x and y Create with CGPointMake(x, y) CGSize C struct with two CGFloats in it: width and height. Create with CGSizeMake(width, height) CGRect C struct with a CGPoint origin and a CGSize size. Create with CGRectMake(x, y, width, height) 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development Coordinates (0,0) Increasing x Origin of View’s coordinate system is upper left Units are “pixels”. For iPhone/iPod touch prior to 4g: A view that starts in portrait mode will be 320 pixels wide and 460 pixels tall or 480 pixels if there’s no status bar A view in landscape mode: 480 pixels wide & 300 (or 320 if no status bar) pixels wide View property bounds is the rectangle, expressed as a location (x,y) and size (width,height) relative to its own coordinate system (0,0) View’s frame is the rectangle, expressed as a location (x,y) and size (width,height) relative to the superview it is contained within (250,85) So is frame.size always the same as bounds.size? No: rotation. Use center and frame to position/size the view in its superview. Increasing y 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development Bounds and Frames View B’s bounds is ((0,0),(200,250)) View B’s frame is ((140,65),(320,320)) 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development Creating a View in Code Use - (id)initWithFrame:(CGRect)aRect as the designated initializer Example: CGRect buttonRect = CGRectMake(20, 20, 120, 37); UIButton *button = [[UIButton alloc] initWithFrame:buttonRect]; button.titleLabel.text = @”Do it!”; [window addSubview:button]; [button release]; 12/24/2018 EEC492/693/793 - iPhone Application Development
Autorotation and Autosizing Autorotation: enables you to use the app in different orientations Three approaches to implementing autorotation: Autosizing: specify the correct autosize attribtes for all UIControl objects in your view Manually reposition the objects when notified that your view is rotating Design two different version of your view, one for portrait mode and another for landscape mode 12/24/2018 EEC492/693/793 - iPhone Application Development
Specifying Rotation Support Autorotation might not be suitable for all apps You can control what orientation is supported in the method AutorotateToInterfaceOrientation: Return yes if all orientations are supported Or you can choose to support one or more specific orientations UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } 12/24/2018 EEC492/693/793 - iPhone Application Development
Approach#1: Handling Rotation Using Autosize Attributes Single-click the UIControl in the view, then press ⌘3 to bring up the size inspector The inner square represents the current object Red arrows inside the inner square represent the horizontal and vertical space inside the selected object Solid: height/width of the object is free to change as the window resizes Dashed: keep the height/width of the object at its original value if possible Click on the arrow: solid->dashed or vice versa Four red “I” shapes outside the inner box represent the distance between the edge of the selected object and the edge of the view Dashed: space is flexible Solid: the amount space should be kept constant if possible Where we set attributes 12/24/2018 EEC492/693/793 - iPhone Application Development
Manually Reposition the Objects Autosizing doesn’t work in all circumstances No Good! 12/24/2018 EEC492/693/793 - iPhone Application Development
Approach#2: Manually Reposition the Objects Introduce an outlet for each UIControl object and connect it In the implementation file, manually position each object depending on the new orientation - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration { if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { button1.frame = CGRectMake(20, 20, 125, 125); button2.frame = CGRectMake(175, 20, 125, 125); button3.frame = CGRectMake(20, 168, 125, 125); …… } else { button2.frame = CGRectMake(20, 155, 125, 125); button3.frame = CGRectMake(177, 20, 125, 125); } 12/24/2018 EEC492/693/793 - iPhone Application Development
Approach#3: Swapping Views Create different views for different orientations Needed only for complex interfaces 12/24/2018 EEC492/693/793 - iPhone Application Development
Accommodating Two Views In the app’s ViewController, add a UIView outlet for each view, and connect them Delete the original view, design and add new views in IB, and connect them Specify the right size of the view in the size inspector For the view that should be displayed by default, connect to the view outlet In the following method, set the right view and transformation self.view.transform = CGAffineTransformIdentity; // should not be here (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval)duration { if (interfaceOrientation == UIInterfaceOrientationPortrait) { self.view = self.portrait; self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0)); self.view.bounds = CGRectMake(0.0, 0.0, 300.0, 480.0); } …. 12/24/2018 EEC492/693/793 - iPhone Application Development
EEC492/693/793 - iPhone Application Development Transformation The transformation statement is to make sure the view is displayed properly self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); Try commenting the above statement and see what happens The following statement is the book should have been deleted self.view.transform = CGAffineTransformIdentity; CGAffineTransformIdentity means you want to reset a view to its original, untransformed state 12/24/2018 EEC492/693/793 - iPhone Application Development
Assignment: build a calculator app Do this after you have done autosize 1, autosize 2, and swap apps 12/24/2018 EEC492/693/793 - iPhone Application Development