The accessories provided to you by the iOS SDK are not sufficient, and you would like to create your own accessories.
Assign an instance of the UIView
class to the accessoryView
property of any instance
of the UITableViewCell
class:
-
(
UITableViewCell
*
)
tableView:
(
UITableView
*
)
tableView
cellForRowAtIndexPath:
(
NSIndexPath
*
)
indexPath
{
UITableViewCell
*
cell
=
nil
;
cell
=
[
tableView
dequeueReusableCellWithIdentifier
:
MyCellIdentifier
forIndexPath:
indexPath
];
cell
.
textLabel
.
text
=
[
NSString
stringWithFormat
:
@"Section %ld, Cell %ld"
,
(
long
)
indexPath
.
section
,
(
long
)
indexPath
.
row
];
UIButton
*
button
=
[
UIButton
buttonWithType
:
UIButtonTypeSystem
];
button
.
frame
=
CGRectMake
(
0.0f
,
0.0f
,
150.0f
,
25.0f
);
[
button
setTitle
:
@"Expand"
forState:
UIControlStateNormal
];
[
button
addTarget
:
self
action:
@selector
(
performExpand
:
)
forControlEvents:
UIControlEventTouchUpInside
];
cell
.
accessoryView
=
button
;
return
cell
;
}
As you can see, this code uses the performExpand:
method as the selector for each
button. Here is the definition of this method:
-
(
void
)
performExpand:
(
UIButton
*
)
paramSender
{
/* Handle the tap event of the button */
}
This example code snippet assigns a custom button to the accessory view of every row in the targeted table. The result is shown in Figure 4-4.
An object of type UITableViewCell
retains a property named
accessoryView
. This is the view you
can assign a value to if you are not completely happy with the built-in
iOS SDK table view cell accessories. After this property is set, Cocoa
Touch will ignore the value of the accessoryType
property and will use the view
assigned to the accessoryView
property as the accessory assigned to the cell.
The code listed in this recipe’s Solution creates buttons for all the
cells populated into the table view. When a button is
pressed in any cell, the performExpand:
method gets called, and if you
are like me, you have probably already started thinking about how you
can determine which cell the sender button belongs to. So now we have to
somehow link our buttons with the cells to which they belong.
One way to handle this situation is to take advantage of the
tag
property of the button instance.
The tag property is a simple integer that people usually use to
associate a view with another object. For instance, if you want to
associate the button with the third cell in your table view, set the
value of the button’s tag property to 3. But there is a problem here:
table views have sections, and every section can have
n number of cells. We, therefore, have to be able
to determine the section as well as the cell that owns our button, and
since the tag can represent only one integer, this makes things more
difficult. Instead of a tag, therefore, we can ask for the superview of
the accessory view, going recursively up the chain of views until we
find the cell of type UITableViewCell
, like so:
-
(
UIView
*
)
superviewOfType:
(
Class
)
paramSuperviewClass
forView:
(
UIView
*
)
paramView
{
if
(
paramView
.
superview
!=
nil
){
if
([
paramView
.
superview
isKindOfClass
:
paramSuperviewClass
]){
return
paramView
.
superview
;
}
else
{
return
[
self
superviewOfType
:
paramSuperviewClass
forView:
paramView
.
superview
];
}
}
return
nil
;
}
-
(
void
)
performExpand:
(
UIButton
*
)
paramSender
{
/* Handle the tap event of the button */
__unused
UITableViewCell
*
parentCell
=
(
UITableViewCell
*
)[
self
superviewOfType
:
[
UITableViewCell
class
]
forView:
paramSender
];
/* Now do something with the cell if you want to */
}
This is a simple recursive method that accepts a view (in this
case our button) and a class name (in this case, UITableViewCell
), then searches in the view’s
super view hierarchy to find the super view that is of the given class.
So it starts with the super view of the given view, and if that super
view is not of the required type, looks at the super view’s super view,
and so on until it finds the super view of the requested class. You can
see that we are using the Class
structure as the first parameter to the superviewOfType:forView:
method. This data
type can hold any Objective-C class name, and it’s great if you are
looking for or asking for specific class names from the programmer.
Get iOS 7 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.