Bronze / Silver Solution


#1

Hi there,
here are my solutions for the challenges:

Bronze:

First of all, make a new class for the cells. In my case I named it ForumViewCell. Then you can make a new xib for positioning of the Labels if you like.
After doing the layout in interface builder and connecting the labels you should have a .h-file that looks like this:

[code]#import <UIKit/UIKit.h>

@interface ForumViewCell : UITableViewCell

@property (nonatomic, weak) IBOutlet UILabel *category;
@property (weak, nonatomic) IBOutlet UILabel *author;
@property (weak, nonatomic) IBOutlet UILabel *title;

@end[/code]

Now go to the ListViewController and override the viewDidLoad method:

[code]- (void)viewDidLoad {
[super viewDidLoad];

UINib *nib = [UINib nibWithNibName:@"ForumViewCell" bundle:nil];

[[self tableView] registerNib:nib forCellReuseIdentifier:@"ForumViewCell"];

}[/code]

and finally update the tableView:cellForRowAtIndexPath: method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    ForumViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ForumViewCell"];
    
    if (cell == nil) {
        cell = [[ForumViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ForumViewCell"];
    }
    RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
    NSArray *temp = [[NSArray alloc] init];
    temp = [[item title] componentsSeparatedByString:@"::"];
    [[cell title] setText:[temp objectAtIndex:1]];
    [[cell category] setText:[temp objectAtIndex:0]];
    NSArray *authorArray = [[NSArray alloc] init];
    authorArray = [[temp objectAtIndex:2] componentsSeparatedByString:@" "];
    [[cell author] setText:[authorArray lastObject]];
    
    return cell;
}

Comment: OK - I didn’t get them from the RSS Feed but why waste something we already got ?

Silver:

You just need to create a UITableView, some buttons for it and update the buttons whenever the user successfully gets to a different web page.
WebViewController.h:

[code]#import <Foundation/Foundation.h>

@interface WebViewController : UIViewController {
UIToolbar *toolbar;
UIWebView *wv;
UIBarButtonItem *backButton;
UIBarButtonItem *forwardButton;
}

@property (nonatomic, readonly) UIWebView *webView;

@end
[/code]

WebViewController.m :

[code]#import “WebViewController.h”

@implementation WebViewController

  • (void)loadView {
    //Create an instance of UIWebView as large as the screen
    CGRect screenFrame = [[UIScreen mainScreen] applicationFrame];
    wv = [[UIWebView alloc] initWithFrame:screenFrame];
    //Tell web view to scale web content to fit within bounds of webview
    [wv setScalesPageToFit:YES];
    [wv setDelegate:self];
    backButton = [[UIBarButtonItem alloc] initWithTitle:@“Back” style:UIBarButtonSystemItemRewind target:self action:@selector(goBack)];
    forwardButton = [[UIBarButtonItem alloc] initWithTitle:@“Forward” style:UIBarButtonSystemItemFastForward target:self action:@selector(goForward)];

    toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake([[UIScreen mainScreen] bounds].origin.x, [[UIScreen mainScreen] bounds].size.height - 114, [[UIScreen mainScreen] bounds].size.width, 50)];
    [toolbar setItems:[NSArray arrayWithObjects:backButton, forwardButton, nil]];
    [self updateButtons];

    [self setView:wv];

    [wv addSubview:toolbar];
    }

  • (void)goBack {
    [wv goBack];
    [self updateButtons];
    }

  • (void)goForward {
    [wv goForward];
    [self updateButtons];
    }

  • (void) updateButtons {
    [backButton setEnabled:[wv canGoBack]];
    [forwardButton setEnabled:[wv canGoForward]];

}

  • (UIWebView *)webView {
    return (UIWebView *)[self view];
    }

  • (void)webViewDidFinishLoad:(UIWebView *)webView {
    [self updateButtons];
    }

@end
[/code]

Hope that helped you out.

Greetings
Joerg


#2

Hello,

I seem to have a problem with code for the bronze challenge that is very similar to yours.

Here is my code

[code]@interface RSSItemCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *title;

@property (weak, nonatomic) IBOutlet UILabel *category;

@property (weak, nonatomic) IBOutlet UILabel *author;

@end[/code]

Then listViewController has this code:

[code]-(void) viewDidLoad
{
[super viewDidLoad];

UINib *nib = [UINib nibWithNibName:@"RSSItemCell" bundle:nil];

[[self tableView] registerNib:nib forCellReuseIdentifier:@"RSSItemCell"];

}[/code]

The debugger stops at the first line of this code.

[code]- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
RSSItemCell *cell = [tableView dequeueReusableCellWithIdentifier:@“RSSItemCell”];

if(cell == nil)
{
    cell = [[RSSItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"RSSItemCell"];
    
    
}

RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];

[[cell title] setText:[item title]];
[[cell category] setText:[item category]];
[[cell author] setText:[item author]];

return cell;

}[/code]

I think it is a problem with my nib file. But I just deleted the default UIView. Then I added a TableViewCell and then 3 labels inside it to create my nib file.

Please help!

Thank You,
Venkat Rao


#3

@vrao423:

I was getting the same error on another challenge. I found that I had set the class for the table view cell and had the outlets connected to File’s Owner. Removing from File’s Owner and setting these on the table view cell fixed this error. Hope this helps!

Matt


#4

For the Silver solution I ended up adding a XIB file to WebViewController so that the toolbar was always the right size and clamped to the bottom when you rotate (and stretched).


#5

At the risk of going slightly off-topic:

[quote]Postby Tiberius » Sun Mar 31, 2013 4:20 am
For the Silver solution I ended up adding a XIB file to WebViewController so that the toolbar was always the right size and clamped to the bottom when you rotate (and stretched).
[/quote]

I have this problem all the time: If I’m building my subviews programmatically, I must hard-code the sizes of the subview I’m adding. But if I add it using Interface Builder, then I get a nice “default” size. (49 points high, I believe, is the magic number I’m after.)

So where does Interface Builder get its default size from? And can I access that default when I’m building subviews programmatically?


#6

Here’s my silver solution:

[code]-(void)viewDidLoad{
UIBarButtonItem *goBackButtonItem;
UIBarButtonItem *goForwardButtonItem;

goForwardButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Go Forward"
                                                      style:UIBarButtonItemStyleBordered target:self
                                                     action:@selector(forwardWebView:)];

goBackButtonItem = [[UIBarButtonItem alloc]initWithTitle:@"Go Back"
                                                   style:UIBarButtonItemStyleBordered
                                                  target:self
                                                     action:@selector(backWebView:)];

self.toolbarItems = [NSMutableArray arrayWithObjects:goForwardButtonItem, goBackButtonItem, nil];

}

-(void)backWebView:(id)sender{
[self.webView goBack];
}

-(void)forwardWebView:(id)sender{
[self.webView goForward];
}[/code]


#7

Hi Guys,

I believe there’s a simpler and easier way to get the toolbar working. Since WebViewController is inside a navigation controller (masterNav), all we have to do is to ask it to display the toolbar, and it will do so automatically for us, placing it at the bottom (full width) and with standard height. The only code you need is:

In WebViewController.m, set the toolbar to show up in viewWillAppear:

- (void)viewWillAppear:(BOOL)animated
{
    // Ask the navigation controller to show the toolbar for us
    [[self navigationController] setToolbarHidden:NO animated:NO];
    
    // Proceed to create all bar buttons
    …
    
    // Set this buttons on the toolbar that is now visible
    [self setToolbarItems:[NSArray arrayWithObjects:previous, next, nil]];
}

And set it to hide itself in viewViewDisappear:

- (void)viewWillDisappear:(BOOL)animated
{
    [[self navigationController] setToolbarHidden:YES animated:NO];
}

Cheers!

Gilmar