Documente Academic
Documente Profesional
Documente Cultură
UINaviga)onController
Stack
of
view
controllers
Naviga)on
bar
Customizing
Naviga)on
Bu_ons
or
custom
controls
Interact
with
the
en)re
screen
UINaviga)onItem
Describes
appearance
of
the
naviga)on
bar
Title
string
or
custom
)tle
view
Lee
&
right
bar
bu_ons
More
proper)es
dened
in
UINaviga)onBar.h
Displaying
a
Title
UIViewController
already
has
a
)tle
property
@property(nonatomic,copy)
NSString
*)tle;
viewController.)tle = @ Detail ;
Display a string, image or predened system item Target + ac)on (like a regular bu_on)
Edit/Done
Bu_on
Very
common
pa_ern
Every
view
controller
has
one
available
Target/ac)on
already
set
up
self.naviga)onItem.leeBarBu_onItem = self.editBu_onItem; // Called when the user toggles the edit/done bu_on - (void)setEdi)ng:(BOOL)edi)ng animated:(BOOL)animated { // Update appearance of views }
Back
Bu_on
Some)mes
a
shorter
back
bu_on
is
needed
self.)tle = @ Hello there, CS193P! ; UIBarBu_onItem *heyBu_on = [[UIBarBu_onItem alloc] initWithTitle:@ Hey! ...]; self.naviga)onItem.backBu_onItem = heyBu_on; [heyBu_on release];
// View 3 - Custom right bar bu_on with a view UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems: [NSArray arrayWithObjects: [UIImage imageNamed:@"up.png"], [UIImage imageNamed:@"down.png"], nil]]; [segmentedControl addTarget:self ac)on:@selector(segmentAc)on:) forControlEvents:UIControlEventValueChanged]; segmentedControl.frame = CGRectMake(0, 0, 90, kCustomBu_onHeight); segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar;segmentedControl.momentary = YES; defaultTintColor = [segmentedControl.)ntColor retain]; // keep track of this for later UIBarBu_onItem *segmentBarItem = [[UIBarBu_onItem alloc] initWithCustomView:segmentedControl]; [segmentedControl release]; self.naviga)onItem.rightBarBu_onItem = segmentBarItem; [segmentBarItem release];
(void)congureToolbarItems {
UIBarBu_onItem
*exibleSpaceBu_onItem
=
[[UIBarBu_onItem
alloc]
initWithBarBu_onSystemItem:UIBarBu_onSystem
ItemFlexibleSpace
target:nil
ac)on:nil];
//
Create
and
congure
the
segmented
control
UISegmentedControl
*sortToggle
=
[[UISegmentedControl
alloc]
initWithItems:[NSArray
arrayWithObjects:@"Ascending,
@"Descending",
nil]];
sortToggle.segmentedControlStyle
=
UISegmentedControlStyleBar;
sortToggle.selectedSegmentIndex
=
0;
[sortToggle
addTarget:self
ac)on:@selector (toggleSor)ng:)
forControlEvents:UIControlEventValueChanged];
// Create the bar button item for the segmented control UIBarButtonItem *sortToggleButtonItem = [[UIBarButtonItem alloc] initWithCustomView:sortToggle]; [sortToggle release]; // Set our toolbar items self.toolbarItems = [NSArray arrayWithObjects: flexibleSpaceButtonItem, sortToggleButtonItem, flexibleSpaceButtonItem, nil]; [sortToggleButtonItem release]; [flexibleSpaceButtonItem release]; }
UITabBarController
Array
of
view
controllers
Tab
bar
UITabBarItem
Title
+
image
or
system
item
Each view controller comes with a tab bar item for customizing
- (BOOL)tabBarController:(UITabBarController *)aTabBar
if (![self hasValidLogin] && (viewController != [aTabBar.viewControllers objectAtIndex:0]) ) { // Disable all but the first tab. return NO; } return YES; }
Table Views
Display
lists
of
content
Single
column,
mul)ple
rows
Ver)cal
scrolling
Large
data
sets
Table Footer
Table Footer
UITabelView
Declaring
methods
that
allow
you
to
congure
the
appearance
of
the
table
view
specifying
the
default
height
of
rows
or
providing
a
view
used
as
the
header
for
the
table
access
to
the
currently
selected
row
as
well
as
specic
rows
or
cells
manage
selec)ons,
scroll
the
table
view,
and
insert
or
delete
rows
and
sec)ons.
UITableView
inherits
from
UIScrollView,
which
denes
scrolling
behavior
for
views
with
content
larger
than
the
size
of
the
window.
UITableView
redenes
the
scrolling
behavior
to
allow
ver)cal
scrolling
only.
A Nave Solution
Table views display a list of data, so use an array [myTableView setList:myListOfStuff]; Issues with this approach
All data is loaded upfront All data stays in memory
UITableViewDataSource
Provide number of sections and rows // Optional method, defaults to 1 if not implemented - (NSInteger)numberOfSectionsInTableView:(UITableView *)table; // Required method - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; Provide cells for table view as needed // Required method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
NSIndexPath
Generic class in Foundation Path to a specific node in a tree of nested arrays
Category on NSIndexPath with helper methods @interface NSIndexPath (UITableView) + (NSIndexPath *)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section; @property(nonatomic,readonly) NSUInteger section; @property(nonatomic,readonly) NSUInteger row; @end
- (void)loadView {
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain]; tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight| UIViewAutoresizingFlexibleWidth; tableView.delegate = self; tableView.dataSource = self; [tableView reloadData]; self.view = tableView; [tableView release]; }
Cell Reuse
When asked for a cell, it would be expensive to create a new cell each time.
- (UITableViewCell *)tableView:(UITableView *)tableView *)dequeueReusableCellWithIdentifier: cellForRowAtIndexPath:(NSIndexPath *)indexPath (NSString *)identifier; { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:... reuseIdentifier:@MyIdenifier] autorelease]; } cell.text = [myStrings objectAtIndex:indexPath.row] return cell; }
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return [regions count]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Number of rows is the number of time zones in the region for the specified section. Region *region = [regions objectAtIndex:section]; return [region.timeZoneWrappers count]; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { // The header for the section is the region name -- get this from the region at the section index. Region *region = [regions objectAtIndex:section]; return [region name]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *MyIdentifier = @"MyIdentifier; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; } Region *region = [regions objectAtIndex:indexPath.section]; TimeZoneWrapper *timeZoneWrapper = [region.timeZoneWrappers objectAtIndex:indexPath.row]; cell.textLabel.text = timeZoneWrapper.localeName; return cell; }
Triggering Updates
When is the datasource asked for its data?
When a row becomes visible When an update is explicitly requested by calling reloadData
UITableView Delegate
Customize appearance and behavior Keep application logic separate from view Often the same object as datasource
Persistent Selection
Responding to Selection
// For a navigation hierarchy... - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Get the row and the object it represents NSUInteger row = indexPath.row id objectToDisplay = [myObjects objectAtIndex:row]; // Create a new view controller and pass it along MyViewController *myViewController = ...; myViewController.object = objectToDisplay; [self.navigationController pushViewController:myViewController animated:YES]; }
UITableViewController
UITableViewController
Convenient starting point for view controller with a table view
Table view is automatically created Controller is table views delegate and datasource
Designated Initializer
-
(id)initWithFrame:(CGRect)frame
reuseIden)er:(NSString
*)reuseIden)er;
P E D
D E T A C E R
Cell Styles
UITableViewCellStyleDefault UITableViewCellStyleSubtitle
UITableViewCellStyleValue1 UITableViewCellStyleValue2
Basic properties
UITableViewCell has an image view and one or two text labels
cell.imageView.image = [UIImage imageNamed:@vitolidol.png]; cell.textLabel.text = @Vitol Idol; cell.detailTextLabel.text = @Billy Idol;
Accessory Types
// UITableView delegate method - (UITableViewCellAccessoryType)tableView:(UITableView *)table accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath;
UITableViewCellAccessoryDisclosureIndicator UITableViewCellAccessoryDetailDisclosureButton UITableViewCellAccessoryCheckmark
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { // Only for the blue disclosure button NSUInteger row = indexPath.row; ... }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = ...; CGRect frame = cell.contentView.bounds; UILabel *myLabel = [[UILabel alloc] initWithFrame:frame]; myLabel.text = ...; [cell.contentView addSubview:myLabel]; [myLabel release]; }
Ques)ons?