1

这里面会有很多代码,对此我深表歉意,但问题是我很难逐步完成这个程序并确定这个东西在哪里创建了 UITableView 的部分。

这从“iOS 编程:大书呆子牧场指南”中的表格视图练习开始,我决定我想更多地探索这个,所以我在 Illustrator 中创建了一些图像并前往城镇。

我已经成功创建:

  • 界面视图

  • UITableView 和 UITableViewCell 在一个单独的部分中,其中填充了“项目”,它们只是随机生成的字符串,如本书示例中所示。(随机形容词、随机名词、随机序号等)

  • 当您点击它们时会变为突出显示状态的其他按钮

  • 在第一个也是唯一一个部分之后的页脚,显示更多似乎可以正常工作的按钮

作为练习,我现在要做的就是将这些随机生成的字符串项中的一半取出,将它们粘贴在表格视图单元格中,然后将它们放置在表格视图的第 2 部分中。似乎是一个相对简单的任务,但我不知道在哪里/如何做。我已经阅读了文档,我想我可能需要实现 insertSections:withRowAnimation: 方法,但我无法在任何地方在线找到一个示例,让我知道如何以一种对我来说有意义的方式实现它程序。

为了简化事情——希望如此——我相信问题出在本文底部的 ItemsViewController.m 文件中。ItemStore 类只是一个名为“allItems”的数组,它包含我之前描述的随机生成的字符串项。AppDelegate 文件中似乎也没有发生对我想要做的事情重要的事情。任何帮助,将不胜感激。提前非常感谢。

物品商店.h

#import <Foundation/Foundation.h>

@class Item;

@interface ItemStore : NSObject {
    NSMutableArray *allItems;
}

+(ItemStore *)sharedStore;
-(NSMutableArray *)allItems;
-(Item *)createItem;

@end

物品商店.m

#import "ItemStore.h"
#import "Item.h"

@implementation ItemStore

// create the singleton ItemStore
+(ItemStore *)sharedStore {
    static ItemStore *sharedStore = nil;
    if (!sharedStore)
        sharedStore = [[super allocWithZone:nil] init];        
    return sharedStore;
}

+(id)allocWithZone:(NSZone *)zone {
    return [self sharedStore];
}

-(id)init {
    self = [super init];
    if (self) {
        allItems = [[NSMutableArray alloc] init];
    }
    return self;
}

-(NSArray *)allItems {
    return allItems;
}

-(Item *)createItem {
    Item *p = [Item randomItem];
    [allItems addObject:p];

    return p;
}

@end

AppDelegate.h

#import <UIKit/UIKit.h>

@class ItemsViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ItemsViewController *viewController;

@end

AppDelegate.m

#import "AppDelegate.h"
#import "ItemsViewController.h"
#import "Item.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    ItemsViewController *itemsViewController = [[ItemsViewController alloc] init];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:itemsViewController];
    [[self window] setRootViewController:navController];

    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];

    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {}
- (void)applicationDidEnterBackground:(UIApplication *)application {}
- (void)applicationWillEnterForeground:(UIApplication *)application {}
- (void)applicationDidBecomeActive:(UIApplication *)application {}
- (void)applicationWillTerminate:(UIApplication *)application {}

@end

ItemsViewController.h

#import <Foundation/Foundation.h>

@interface ItemsViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

{
    UIView *underView;
    UITableView *ivarTableView;
}

@property (nonatomic, readwrite) UITableView *ivarTableView;

-(id)init;
-(id)initWithStyle:(UITableViewStyle)style;
-(void)insertSections:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation;
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

@end

项目视图控制器.m

#import "ItemsViewController.h"
#import "Item.h"
#import "ItemStore.h"

@implementation ItemsViewController

@synthesize ivarTableView;

-(void)viewDidLoad {
    [super viewDidLoad];

    CGFloat startingPoint = 33.0;
    CGRect bounds = self.view.bounds;
    bounds.origin.y = startingPoint;
    bounds.size.height -= startingPoint;

    self.ivarTableView = [[UITableView alloc] initWithFrame:bounds style:UITableViewStyleGrouped];
    self.ivarTableView.dataSource = self;
    self.ivarTableView.delegate = self;
    self.ivarTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
    self.ivarTableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.ivarTableView];

    // create background, custom navigation bar, and a few other images/buttons, 
    // and some buttons that get placed in the footer.  all of these work fine.
    // ...

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection: (NSInteger) section
{
    // this method is a little unclear to me, but I've got everything in the footer working fine, so I haven't worried about it at this point.
    return 0.0;
}

// so far, init{} just creates a random amount of 'Items', which are just random strings so there's something to populate the UITableViewCells.
-(id) init {
    if (self) {
        int r = arc4random() % 10;
        NSLog(@"Number of cells in the table view should be:  %d", r);
        for (int i = 1; i <= r; i++) {
            [[ItemStore sharedStore] createItem];
        }
    }
    return self;
}

-(void)insertSections:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation{
    // I think this is where I need to--create another section?--and send the second section the data that is going to be used in the second section's cells, but I'm having trouble tracing the flow of this program.
}

// Asks the delegate for the height to use for a row in a specified location and sends
// the appropriate size, based upon which image is going to be displayed for the particular cell.
// Top cell is a taller height, middle and bottom cell(s) are the same height.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSInteger lastRow = [self tableView:ivarTableView numberOfRowsInSection:1] - 1;
    NSInteger rowsAmount = [self tableView:ivarTableView numberOfRowsInSection:[indexPath section]];

    if (indexPath.row == 0 && rowsAmount != 1) {
        return 95.0;
    } else if (indexPath.row == 0 && rowsAmount == 1) {
        return 137.0;
    } /*end change*/ else if (indexPath.row == lastRow) {
        return 74.0;
    } else {
        return 74.0;
    }
}

-(UITableViewCell *)tableView:(UITableView *)tableView
        cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];

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

    NSInteger sectionsAmount = [tableView numberOfSections];
    NSInteger rowsAmount = [self tableView:ivarTableView numberOfRowsInSection:[indexPath section]];

    if (rowsAmount == 1) {
        cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellTypeOne.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

        cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellTypeOneTouched.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

    } else if (rowsAmount == 2) {

        if ([indexPath section] == 0 && [indexPath row] == 0) {

            cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellTypeOneMulti.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

            cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellTypeOneMultiTouched.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
        } else {

            cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellBottom.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

            cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellBottomTouched.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
        }

    } else if (rowsAmount >= 3) {

        if ([indexPath section] == 0 && [indexPath row] == 0){

            cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellTypeOneMulti.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

            cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellTypeOneMultiTouched.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];            

        } else if ([indexPath section] == sectionsAmount - 1 && [indexPath row] == rowsAmount - 1) {

            cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellBottom.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

            cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellBottomTouched.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

        } else {

            cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellMiddle.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];

            cell.selectedBackgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"cellMiddleTouched.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
            }
        }

    // gets rid of the white box that would bound the text of the cell
    [[cell contentView] setBackgroundColor:[UIColor clearColor]];
    [[cell backgroundView] setBackgroundColor:[UIColor clearColor]];
    [cell setBackgroundColor:[UIColor clearColor]];

    /* Set the text of the cell to the description of the item that is at the nth index of items, where n = row this cell will appear in on the tableView */
    Item *p = [[[ItemStore sharedStore] allItems] objectAtIndex:[indexPath row]];
    [[cell textLabel] setText:[p description]];
    [[cell textLabel] setHighlightedTextColor:[UIColor whiteColor]];
    [[cell textLabel] setTextColor:[UIColor blackColor]];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    return cell;
}

/* return count of ItemStore's allItems array */
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [[[ItemStore sharedStore] allItems] count];
}

// ...

@end
4

2 回答 2

1

UITableView 请求特定部分和行的单元格,调用方法

-(UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath

来自其“数据源”。

在这种情况下,数据源是 ItemsViewController。因此,在上述方法中,参数之一是“indexPath”,它是指示您必须返回单元格的部分和行的对象。

您可以知道它是否需要第 2 节比较:

if(indexPath.section == 2)
{
    //Do something for section 2
}

编辑:

此外,要获得一个包含两个部分的表,您必须实现该方法

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 2; //Return the number of sections you what
}

在 ItemsViewControlle.m 中。

祝你好运!

于 2012-12-04T20:40:43.810 回答
1

我在您的代码中看不到以下方法,这是您的 tableview 将调用以了解它应该创建多少部分的方法。

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return numberOfSectionYouWant;
}

此外,最好让控制器成为子类,UITableViewController而不是UIViewController添加协议的地方。它将为您节省许多错误。

insertSections:withRowAnimation: 

如果您需要在运行时添加一个部分,可以在之后直接在您的 tableview 上调用。

于 2012-12-04T20:47:54.350 回答