【问题标题】:loading to a xib from plist using grouped tableview使用分组表视图从 plist 加载到 xib
【发布时间】:2011-08-08 00:02:10
【问题描述】:

我是一名新手,正在开发一个应用程序,该应用程序具有从 plist 填充的分组表视图。每个单元格都有一个图像、标题和描述。一切正常。我在 plist 中还有一个控制器键,用于加载视图控制器和 xib。现在为每个选定的单元格加载不同的视图控制器。然而,加载相同的视图控制器和 xib 但只是从同一个 plist 中填充变量(图像、文本和声音文件)会很好。有人可以帮我做到这一点。这是我的代码

//  RootViewController.h
//  TableViewPush
//

#import <UIKit/UIKit.h>


@interface RootViewController :  UITableViewController <UITableViewDelegate, UITableViewDataSource>  {

    NSArray *tableDataSm;

}
- (IBAction)howToUse: (id) sender;  

@property (nonatomic, retain) NSArray *tableDataSm;


@end




//  RootViewController.m
//  TableViewPush
//

#import "RootViewController.h"
#import "Location One.h"
#import "HowToUseViewController.h"
#import "TableViewPushAppDelegate.h"


@implementation RootViewController 

@synthesize tableDataSm;


- (IBAction)howToUse: (id) sender;  
{
    HowToUseViewController *how = [[HowToUseViewController alloc] initWithNibName:@"HowToUse"  bundle:nil];
    [self.navigationController pushViewController:how animated:YES];
    [how release];
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *path = [[NSBundle mainBundle] pathForResource:@"TableDataSm" ofType:@"plist"];
    self.tableDataSm = [NSArray arrayWithContentsOfFile:path];


    self.title = @"Studios";
}
/*
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}
 */
#pragma mark -
#pragma mark Table view data source

- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section {
    const NSDictionary *const sectionData = [self.tableDataSm objectAtIndex:section];
    return [sectionData objectForKey:@"header"];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [self.tableDataSm count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    const NSDictionary *const data = [self.tableDataSm objectAtIndex:section];
    const NSArray *const rows = [data objectForKey:@"rows"];
    return [rows count];
}
- (NSDictionary *)rowForIndexPath:(NSIndexPath *)indexPath {
    const NSDictionary *const data = [self.tableDataSm objectAtIndex:indexPath.section];
    const NSArray *const rows = [data objectForKey:@"rows"];
    return [rows objectAtIndex:indexPath.row];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    const NSDictionary *const row = [self rowForIndexPath:indexPath];

    static NSString *CellIdentifier = @"CellIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = [row objectForKey:@"text"];
    cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

    cell.detailTextLabel.text = [row objectForKey:@"detailText"];
    // This assume the image file you specify exists in your bundle of course!
    NSString *imageFileName = [row objectForKey:@"image"];
    cell.imageView.image = [UIImage imageNamed:imageFileName];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    const NSDictionary *const row = [self rowForIndexPath:indexPath];

    NSString *wantedClassName = [row objectForKey:@"controller"];

    UIViewController *const vc = [[NSClassFromString (wantedClassName) alloc] init];
    NSLog(@"controller is -%@-", wantedClassName);
    [self.navigationController pushViewController:vc animated:YES];

    [vc release];  

}


#pragma mark -
#pragma mark Memory management

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Relinquish ownership any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {

    [super viewDidUnload];

    // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
    // For example: self.myOutlet = nil;
}
- (void)dealloc {

    [super dealloc];
}


@end



//  Location One.h
//  TableViewPush
//

#import <UIKit/UIKit.h>
#import "RootViewController.h"
#import  <AVFoundation/AVAudioPlayer.h>
#import <AudioToolbox/AudioToolbox.h>


@interface   Location_One: UIViewController <AVAudioPlayerDelegate>  {


    AVAudioPlayer *theAudio;
}   

-(IBAction)pushButton;


-(IBAction)play;
-(IBAction)stop;
-(IBAction)pause;


@end





//  Location One.m
//  TableViewPush
//

#import "Location One.h"
#import "TableViewPushAppDelegate.h"
#import <AVFoundation/AVAudioPlayer.h>

@implementation Location_One



-(id) init{
    if((self = [super initWithNibName:@"Location One" bundle:nil])){

    }
    return self;
}


-(IBAction)pushButton  {

    NSString *path = [[NSBundle mainBundle] pathForResource:@"AudioOne" ofType:@"mp3"];
    if (theAudio)[theAudio release];
    theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
    theAudio.delegate = self;
    [theAudio play];
}



-(IBAction)play {
    [theAudio play];
}
-(IBAction)stop {
    [theAudio stop];
}
-(IBAction)pause {
    [theAudio pause];
}

-(void)beginInterruption{
    [theAudio pause];

}

-(void)endInterruptionWithFlags{
    [theAudio play];
}




- (void)viewDidLoad {


    NSLog(@"InView did load");


    [super viewDidLoad];
    self.title = @"Glass Illusions Studio";
}


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc. that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];

    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {

    [theAudio release];

    [Location_One release];
    [super dealloc];
}


@end




<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
     <dict>
          <key>header</key>
          <string>85710</string>
          <key>rows</key>
          <array>
               <dict>
                    <key>text</key>
                    <string>52 Glass Illusions Studio</string>
                    <key>detailText</key>
                    <string>150 S Camino Seco, #119</string>
                    <key>image</key>
                    <string>VisualFEight.png</string>
                    <key>controller</key>
                    <string>Location_One</string>
                    <key>picture</key>
                    <string>VisualOne.png</string>
                    <key>audio</key>
                    <string>AudioOne.mp3</string>
                    <key>description</key>
                    <string>TextOne</string>
               </dict>
               <dict>
                    <key>text</key>
                    <string>53 Illusions Gallery</string>
                    <key>detailText</key>
                    <string>150 S Camino Seco, #150</string>
                    <key>image</key>
                    <string>VisualFTen.png</string>
                    <key>controller</key>
                    <string>Location_One</string>
                     <key>picture</key>
                    <string>VisualTwo.png</string>
                    <key>audio</key>
                    <string>AudioTwo.mpg</string>
                    <key>description</key>
                    <string>TextTwo</string>
               </dict>
               <dict>
                    <key>text</key>
                    <string>54 Adam Noman Metal Sculpture</string>
                    <key>detailText</key>
                    <string>7208 E Paseo San Andres</string>
                    <key>image</key>
                    <string>VisualFEleven.png</string>
                    <key>controller</key>
                    <string>Location_One</string>
                     <key>picture</key>
                    <string>VisualThree.png</string>
                    <key>audio</key>
                    <string>AudioThree.mp3</string>
                    <key>description</key>
                    <string>TextThree</string>
               </dict>
               <dict>
                    <key>text</key>
                    <string>54 Firefly Glass Gallery</string>
                    <key>detailText</key>
                    <string>8002 E Broadway Blvd</string>
                    <key>image</key>
                    <string>VisualFSeven.png</string>
                    <key>controller</key>
                    <string>Location_One</string>
                     <key>picture</key>
                    <string>VisualFour.png</string>
                    <key>audio</key>
                    <string>AudioFour.mp3</string>
                    <key>description</key>
                    <string>TextFour</string>
               </dict>
                <dict>
                    <key>text</key>
                    <string>55 Red Door Studio</string>
                    <key>detailText</key>
                    <string>6323 E Printer Udell St.</string>
                    <key>image</key>
                    <string>VisualFFourteen.png</string>
                    <key>controller</key>
                    <string>Location_One</string>
                     <key>picture</key>
                    <string>VisualFive.png</string>
                    <key>audio</key>
                    <string>AudioFive.mp3</string>
                    <key>description</key>
                    <string>TextFive</string>
               </dict>
          </array>
     </dict>
     <dict>
          <key>header</key>
          <string>85711</string>
          <key>rows</key>
          <array>
               <dict>
                    <key>text</key>
                    <string>56 Fuente Y Claro</string>
                    <key>detailText</key>
                    <string>4001 E Montecito St.</string>
                    <key>image</key>
                    <string>VisualFFifteen.png</string>
                    <key>controller</key>
                    <string>Location_One</string>
                     <key>picture</key>
                    <string>VisualSix.png</string>
                    <key>audio</key>
                    <string>AudioSix.mp3</string>
                    <key>description</key>
                    <string>TextSix</string>
               </dict>
          </array>
     </dict>
</array>
</plist>

【问题讨论】:

    标签: objective-c plist tableview


    【解决方案1】:

    这是一种数据驱动模式的实现,用于在选择不同单元格时加载各种 VC。我展示了 LocationOne 的实现,它可以用作新 Location VC 的模板或超类。我建议您仔细研究使用属性来管理数据成员的内存(就像我在 LocationOne 中所做的那样)。它确实让内存管理变得轻而易举。

    RootViewController.m

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
        NSDictionary *const row = [self rowForIndexPath:indexPath];
    
        NSString *wantedClassName = [row objectForKey:@"controller"];
    
        UIViewController *const vc = [[[NSClassFromString (wantedClassName) alloc] autorelease]
    
    
        if ([vc isKindOfClass:[Location_One class]])
        {
            Location_One* loVC = (Location_One*)vc;
            loVC.myImage = [row objectForKey:@"picture"];
            loVC.myText = [row objectForKey:@"decription"];
            loVC.mySoundFile = [row objectForKey:@"audio"];
        }
    
        NSAssert(vc, @"viewController should exist!");
    
        [self.navigationController pushViewController:vc animated:YES];
    
        // There's no need to release the new VC because it is autoreleased 
    }
    
    
    // LocationOne.h
    //
    
    @interface   Location_One: UIViewController <AVAudioPlayerDelegate>  
    {
        AVAudioPlayer *theAudio;
        NSString* myImage;
        NSString* myText;
        NSString* myAudio;
    }   
    
    @property (nonatomic, retain) AVAudioPlayer* theAudio;
    @property (nonatomic, retain) NSString* myImage;
    @property (nonatomic, retain) NSString* myText;
    @property (nonatomic, retain) NSString* myAudio;
    
    -(IBAction)pushButton;
    -(IBAction)play;
    -(IBAction)stop;
    -(IBAction)pause;
    @end
    
    
    // LocationOne.m
    //
    
    #import "Location One.h"
    #import "TableViewPushAppDelegate.h"
    #import <AVFoundation/AVAudioPlayer.h>
    
    @implementation Location_One
    
    @synthesize theAudio;
    @synthesize myImage;
    @synthesize myText;
    @synthesize myAudio;
    
    -(IBAction)pushButton:(id)sender
    {
        NSString *path = [[NSBundle mainBundle] pathForResource:myAudio ofType:@"mp3"];
    
        // theAudio is a property, therefore you can assigning it to self. will bump the retain count.
        // and decrement  the retain count for any previous audio players (releasing them).
    
        // Since an audio player can only set the URL at creation time, the create a new instance.
        // Using properties rather than just class members allows you to handle memory without explicit retains/releases
        self.theAudio = [[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL] autorelease];
        self.theAudio.delegate = self;
    
    }
    
    -(IBAction)play {
        [theAudio play];
    }
    
    -(IBAction)stop {
        [theAudio stop];
    }
    
    -(IBAction)pause {
        [theAudio pause];
    }
    
    -(void)beginInterruption{
        [theAudio pause];    
    }
    
    -(void)endInterruptionWithFlags{
        [theAudio play];
    }
    
    - (void)viewDidLoad 
    {
        [super viewDidLoad];
        self.title = @"Glass Illusions Studio";
    }
    
    - (void)viewDidUnload 
    {
        [super viewDidUnload];
        // Only release theAudio when the view gets an unload message.
        // This is because it's recreated as needed.
        self.theAudio = nil;
    }
    
    - (void)dealloc 
    {
        // I'm not sure why you were doing a self-retain or self-release but I 
        // suggest against it. Let the NavigationController handle the lifetime
        // of this object.
        // [Location_One release];
    
        self.theAudio = nil;
        self.myImage = nil;
        self.myText = nil;
        self.myAudio = nil;
    
        [super dealloc];
    }
    
    // This method is an older way of iOS handling memory shortages.
    // You don't need it as long as you implement viewDidUnload.
    // - (void)didReceiveMemoryWarning 
    
    @end
    

    【讨论】:

    • 我认为我没有说清楚。视图控制器位置一具有 xib 位置一。它有一个图像视图、一个文本视图和一个要播放的声音文件。这些在 plist 中的变化取决于所选的单元格。我想要做的是加载相同的视图控制器和 xib,但更改图像视图、文本视图和声音文件以反映 plist 中的内容作为描述、图片和音频。可以做到这一点,如果可以的话怎么做。我一直在到处寻找,到处问,但没有成功。感谢您回复我。
    • 好的,我想我理解了你原来的问题,但是让我问你这个:
    • 是的,我想我理解了你原来的问题,但是让我问你:当你说“相同的视图控制器”时,你是指相同的实例还是相同的类?我相信你的意思是同一个类,它是一个简单的 UIViewController,它有一个 UITextView、UIImageView 和音频......这就是你想要/需要的。您只需要在选择单元格时改变这些值。如果是这种情况,那么我将始终打开 Location_One* vc = [[[LocationOne alloc] initWithValues:(x, y, z)] autorelease];并将其推到导航控制器上?这清楚吗?
    • 是也不是,我明白你的意思。是的,但不是,因为我不明白如何 initWithValues:(x,y,z)。你能给我举个例子或指点我一个教程来告诉我如何做到这一点吗?这很有帮助。变量是从 plist 中提取的还是从哪里提取的?
    • 你能告诉我为什么你的 pList 包含一个 ViewController (Location_One) 吗?我正在努力了解您的大局。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2016-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多