Archive for the ‘iPhone’ Category

Presence 3 – Part 2 Custom Delegation

Thursday, August 6th, 2009

Setting up a custom delegate seems pretty straightforward. In this case we want the calling class to understand what the child is saying to it.

I’ve set up my PersonListTableViewController with a toolbar item that allows me to update my twitter status. It does so by popping up a new modal window where I type in my status and hit done to send it over to twitter. Here’s where I do that. In the main view controller I add the method that will trigger my modal window. didTapEditStatusButton:

-(void)didTapEditStatusButton
{
StatusComposeViewController *statusComposeViewController = [[StatusComposeViewController alloc] init];
statusComposeViewController.delegate = self;

[self presentModalViewController:statusComposeViewController animated:YES];
[statusComposeViewController release];
}

The first thing that happens here is the modal window is instantiated.
Next I assign the delegate of the modal window to the main view controller. This is how we get the parent to listen to the child. Or, I guess this is where we tell the child who it’s daddy is.
When this is done all we need to do is present the controller, then release.

Because it is considered “Bad Form” for a modal window to dismiss itself, I’ll use delegation to let my parent view controller PersonListTableViewController know what the child view controller (my modal window) has done.

So the first thing I need to do is create my modal view. I’m going with the suggested StatusComposeViewController. Nothing new here, I’m subclassing UIViewController.

In the class header for my new view I need to add the delegation protocol. First thing I need to remember to do is declare the delegate protocol.

@protocol StatusComposeViewControllerDelegate;

Then I create the protocol and give it a couple of optional methods:

@protocol StatusComposeViewControllerDelegate
@optional
-(void)statusViewControllerDidSetStatus:(StatusComposeViewController *)controller didSetStatus:(NSString *)text;
-(void)statusViewControllerDidCancel:(StatusComposeViewController *)controller;
@end

This essentially declares these methods for whatever controller you specify as your delegate.

Moving back into my delegate (PersonListTableViewController) I’m going to need to implement the methods I’ve defined in my modal view. For this post I’ll just do one, the statusViewControllerDidSetStatus method.

-(void)statusViewControllerDidSetStatus:(StatusComposeViewController *)controller didSetStatus:(NSString *)text
{
[TwitterHelper updateStatus:text forUsername:username withPassword:password];
[self didFinishWithModalViewController];
}

A simple method for updating twitter status. The TwitterHelper class is provided in the course files. didFinishWithModalViewController is a method I’m using for cleanup and dismissal of the modal window. (Dismiss using [self didFinishWithModalViewController]). Any view can only have one modal view up at any given time, so we don’t need to tell this method which modal view to dismiss… it will always be the current modal view.

What did I miss…

Ok in the modal view controller StatusComposeViewController I need to implement the methods I’ll use to hit the delegate methods to perform the actions that the modal view is intended for.

- (IBAction)doneButtonPressed:(id)sender{
if([self.delegate respondsToSelector:@selector(statusViewControllerDidSetStatus:didSetStatus:)]){
[self.delegate statusViewControllerDidSetStatus:self didSetStatus:textField.text];
}
}

It is important to make sure you find out weather or not the delegate has implemented the method you’re going to try to call. This is done in the first line. Then we perform the operation.

Presence 2

Wednesday, June 10th, 2009

I found cell rendering to be the biggest challenge in this assignment.

The process of making this work is a bit drawn out. The first thing I need to do is calculate what my

rowHeight

needs to be. This is done by overriding the

heightForRowAtIndexPath

method in my TableViewController.

  1. Grab the string that needs to fit in the cell.
  2. Set its font size.
  3. Create a
    CGSize

    object using my cell width (I used a static width in this case) and a max hieght of 1000 (hopefully I wouldn’t need more height than that). This is done using

    CGSizeMake(280, 1000);
  4. Assign it a size based on the font, font size, and line break mode
  5. Then return the height, with a bit of padding
    return size.height + 20;

Once the row height has been calculated I init my label with a

CGRect

that specifies the label size based on the dimensions of my cell, then I add it to the

contentView

of the cell.
Now in order to make the label multiline enabled I first need to specify the

numberOfLines

property. I’m setting it to equal 0. This means that I’ll get as many lines as needed to fit the text (I don’t know exactly why this works the way it does. I could also put it some arbitrary number, and it would still work, but the maximum number of line breaks would be limited by that number). Then I need to set the

autoResizingMask

property of my label to

UIViewAutoresizingFlexibleHeight

. Also, I have to make sure I’m using the same font and font size that I specified in the

heightForRowAtIndexPath

method (

setFont:[UIFont systemFontOfSize:14.0]

). The it’s just a matter of setting the text value, adding it to the cell and releasing it.

Assignment 3

Tuesday, May 26th, 2009

I was having a very hard time with this one. My problem was that I still didn’t fully understand the relationship between XCode and Interface Builder. I’m not saying I know it all now, but I think I’m closer.

I had been struggling with the seeming lack of instantiation for my controller. I couldn’t find anywhere in my generated code (i.e. code created after dragging an object into my nib file window, setting up outlets, actions, etc, and selecting File>Write Class Files) where my Controller class was being instantiated. I wanted to assume that the nib takes care of this, well, it does, or, I do. By virtue of dragging the object into my nib window and assigning a class to it I am instantiating that class (it’s all spelled out for me right there in the description of the object, I missed it initially).

This helps to allow connections to make more sense to me. Once I got past the hocus pocus of magical object instantiation, I could look at connections more simply, as just connections, not some nebulous directive to instantiate as well. This had me thinking though. I was initializing my PolygonView class in my controller’s init method. It didn’t seem in keeping with my theory that interface builder takes care of instantiation, so I pulled the polygon init code out of my controller class to see how far south things would go. My code compiled without a problem, and my app ran just as well as before, except better, because now I wasn’t wasting memory instantiating an unused object.

My controller class keeps track of my view(s) and model(s). Within my controller I set up instance vars. I use interface builder to point them to the objects they represent.

Just to get this to sink in a bit more I played around with multiple instances of my PolygonView class. Adding a couple more poly view objects for a preview of the next and previous polygons.