IOS:通过 tableView 导航并在下一个视图中显示表视图数据

Posted

技术标签:

【中文标题】IOS:通过 tableView 导航并在下一个视图中显示表视图数据【英文标题】:IOS: Navigate through tableView and show table view data on next view 【发布时间】:2015-10-14 06:13:38 【问题描述】:

在我的项目中,我使用了自定义 UITableView,其中我传递了 2 个数组(图像和名称),数组显示在 UITableView 上。现在我想在单击表格的任何单元格时查看UITableViewCell 的凭据以显示在下一个视图中,在该视图中我使用UIImageView(用于图像)和UILabel(用于名称显示)。我还导入了我必须在其上显示图像和名称的 VC。 请建议我在另一个视图上显示名称和图像的代码

我正在使用以下代码

.h 文件

#import <UIKit/UIKit.h>

@interface FriendsViewController : UIViewController<UISearchDisplayDelegate , UISearchBarDelegate, UITableViewDataSource, UITableViewDelegate>

    
        UITableView *friendslisttable;
        NSMutableArray *friendslist;
        NSMutableArray *friendsnamearray;
        NSMutableArray *profilepicarray;
        UIImageView * frndprofpic;
        UILabel *friendnamelabel;

        NSArray *searchResults;
    
    @end

.m 文件

- (void)viewDidLoad 

    [super viewDidLoad];
    self.title = @"Friends";

    friendslisttable = [[UITableView alloc]initWithFrame:CGRectMake(0,110 , self.view.frame.size.width, self.view.frame.size.height)] ;
    friendslisttable.delegate = self;
    friendslisttable. dataSource = self;
    [self.view addSubview:friendslisttable];

    friendsnamearray = [[NSMutableArray alloc]initWithObjects:@"friend1",@"friend12",@"friend13",@"friend14",@"friend15",@"friend16",@"friend17",@"friend18",@"friend19",@"friend20",@"friend21 ",@"friend22",@"", nil];

    profilepicarray = [[NSMutableArray alloc]initWithObjects:@"download3.jpeg", @"12045540_717548405011935_7183980263974928829_o.jpg" , @"download4.jpeg", @"download5.jpeg", @"download6.jpg", @"download12.jpeg", @"download13.jpeg", @"download16.jpeg",@"download3.jpeg", @"download6.jpg", @"download12.jpeg", @"download16.jpeg", @"  ",  nil];


#pragma mark - TableView Delegate Method -------------------->>>>

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

    return 60;
    

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    if (tableView == self.searchDisplayController.searchResultsTableView) 
        return searchResults.count;
    
    else 
        return friendsnamearray.count;
    


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

    NSString *cellidentifier = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellidentifier ];

    if(!cell) 
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellidentifier];
        cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
    
    friendslisttable  = nil;
    if (tableView == self.searchDisplayController.searchResultsTableView) 
        friendslisttable = [searchResults objectAtIndex:indexPath.row];
     else
    
        friendslisttable = [friendsnamearray objectAtIndex:indexPath.row];
    

    frndprofpic = [[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 50, 50)];

    frndprofpic.image=[UIImage imageNamed:[profilepicarray objectAtIndex:indexPath.row]];
    [cell.contentView addSubview:frndprofpic];

    friendnamelabel = [[UILabel alloc]initWithFrame:CGRectMake(70, 10, 250, 50)];
    friendnamelabel.text = [friendsnamearray objectAtIndex:indexPath.row];
    friendnamelabel.font = [UIFont fontWithName:@"ChalkboardSE-Regular" size:20];
    [cell.contentView addSubview:friendnamelabel];

    return  cell;


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    if (!indexPath.row) 
        ProfileViewController *u = [[ProfileViewController alloc]init];
        [self.navigationController pushViewController:u animated:YES];
    

【问题讨论】:

检查这个...***.com/questions/22759167/… 我正在使用自定义表格视图,请告诉我我必须在 didSelectRow 方法中进行哪些更改 【参考方案1】:

对于像您这样的情况,我建议您将表格视图单元格子类化。在您的情况下为个人资料图像和名称创建 2 个属性。覆盖这些属性的设置器并根据需要设置视图组件。

在没有选择行的情况下,您现在可以使用自定义单元格的相同属性,这些属性可以在推送之前设置为目标控制器的属性。

但是,如果您想正确执行此操作,则应始终使用模型类(MyUserClass),然后可以将其插入自定义单元格和视图控制器中。这样,您只需为输入和输出保留一个属性。此外,如果您的模型类发生更改或者您需要显示更多数据,则不会有太多代码更改。例如,假设您的单元格保持不变,但在视图控制器上您还希望添加用户位置:您需要做的就是将 location 属性添加到模型类,然后仅在视图控制器中使用它。 (如果您使用多个属性执行此操作,则单元格将需要收集该属性,即使它不显示它)。

让我举一个很好的例子,说明与表格视图、表格视图单元格和所有者(通常是视图控制器)进行通信的一些用途。

这展示了如何很好地从单元格中获取数据,以及如何将自定义控件(按钮)连接到单元格并使用适当的数据通知事件的所有者。

请注意,这一切都是以编程方式完成的,因此您可以看到所有代码已完成。不过,这一切都可以通过情节提要完成。

标题:

#import <UIKit/UIKit.h>

@class MyModel;
@class MyTableViewCell;

@interface MyViewController : UIViewController

- (void)specialCellButtonPressed:(MyTableViewCell *)sender selectedModel:(MyModel *)model;

@end

来源:

#import "MyViewController.h"


#pragma mark - My model
/*
 MyModel:
 Model that we will use to hold the data
*/
@interface MyModel : NSObject

@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *descriptionText;

@end

#pragma mark - My model
/*
 MyTableViewCell:
 Custom table view cell to show the MyModel data
 */
@interface MyTableViewCell : UITableViewCell

@property (nonatomic, strong) MyModel *model;

@property (nonatomic, strong) UIButton *specialButton; // have the secondary action
@property (nonatomic, weak) MyViewController *owner; // note this may also be solved with a custom delegate but we want to bind this one to a concrete class that has type of MyViewController. Be careful to set this property to "weak"

@end

@implementation MyTableViewCell

- (void)setModel:(MyModel *)model

    _model = model; // standard asignment

    // set some views to show the actual data
    self.textLabel.text = model.title;
    self.detailTextLabel.text = model.descriptionText;


#pragma mark - custom button on the cell

// lazy load for the button
- (UIButton *)specialButton

    if(_specialButton == nil)
    
        // put the button on the right side of the frame
        _specialButton = [[UIButton alloc] initWithFrame:CGRectMake(.0f, .0f, self.contentView.frame.size.width*.5f, self.contentView.frame.size.width*.5f)];
        [_specialButton addTarget:self action:@selector(spectialButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:_specialButton];
    
    return _specialButton;


#pragma mark - layout

- (void)layoutSubviews

    [super layoutSubviews];
    // reposition the custom view if needed
    self.specialButton.frame = CGRectMake(.0f, .0f, self.contentView.frame.size.width*.5f, self.contentView.frame.size.width*.5f);


#pragma mark - actions

- (void)spectialButtonPressed:(id)sender

    // just report this to the delegate or rather the owner in this case
    [self.owner specialCellButtonPressed:self selectedModel:self.model];


@end


#pragma mark - My model
/*
 MyViewController:
 A view controller showing the table view
 */
@interface MyViewController ()<UITableViewDataSource, UITableViewDelegate>

@property (nonatomic, strong) NSArray *models;
@property (nonatomic, strong) UITableView *tableView;

@end

@implementation MyViewController

#pragma mark - lifetime

- (void)viewDidLoad 
    [super viewDidLoad];

    // fill some data for our table view
    NSMutableArray *models = [[NSMutableArray alloc] init];
    for(NSInteger i=0; i<24; i++)
    
        MyModel *model = [[MyModel alloc] init];
        model.title = [NSString stringWithFormat:@"Cell %d", (int)(i+1)];
        model.descriptionText = [NSString stringWithFormat:@"This is a cell with index: %d", (int)(i)];
        [models addObject:model];
    
    self.models = models;


- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    [self.tableView reloadData];


// lazy load from table view
- (UITableView *)tableView

    if(_tableView == nil)
    
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(.0f, .0f, self.view.frame.size.width, self.view.frame.size.height)];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        [self.view addSubview:_tableView];
    
    return _tableView;


#pragma mark - layout

- (void)viewWillLayoutSubviews

    [super viewWillLayoutSubviews];
    // reposition the table view if needed
    self.tableView.frame = CGRectMake(.0f, .0f, self.view.frame.size.width, self.view.frame.size.height);


#pragma mark - table view

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return self.models.count;

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

    return 44.0f;

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

    MyTableViewCell *cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
    cell.model = self.models[indexPath.row]; // assign the model from our list
    cell.owner = self;
    return cell;


// standard cell selection
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    MyTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    MyModel *model = cell.model;
    /*
     Alternative if we have the data array (as we do in this case):

     MyModel *model = self.models[indexPath.row];

     */

    NSLog(@"Selected model: %@", model);
    // do whatever with the model


#pragma mark - special

- (void)specialCellButtonPressed:(MyTableViewCell *)sender selectedModel:(MyModel *)model

    NSLog(@"Special button for model pressed: %@", model);


@end




@implementation MyModel

// override description to get some usefull data
- (NSString *)description

    return [NSString stringWithFormat:@"<%p> %@ (%@)", self, self.title, self.descriptionText];


@end

【讨论】:

【参考方案2】:

在 ProfileViewController 中创建属性:

 @property (strong, nonatomic)UIImage *profilePicture;   
 @property (strong, nonatomic)NSString *name;

如下修改你的 didSelectMethod。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
if (!indexPath.row) 
    ProfileViewController *u = [[ProfileViewController alloc]init];
    UIImage *profileImage = [profilepicarray objectAtIndex:indexPath.row];
    NSString *name = [friendsnamearray objectAtIndex:indexPath.row];
    u.profilePicture = profileImage;
    u.name = name;
    [self.navigationController pushViewController:u animated:YES];
    

【讨论】:

图片未显示或图片和名称都显示?检查 profilepicarry 是否包含 UIImage 对象。在 profileviewcontroller 的 viewdidLoad() 中添加断点并检查 self.profileImage 和 self.name 是否包含我们从 tableviewcell 传递的值。让我知道它是否有效。谢谢 这意味着问题出在填充 UIImageView 和 UILabel 时。在这些区域添加断点。检查结果是否相同。然后确保正确填写 uiimageview 和 uilabel。 而且点击只在第一行工作,我希望它在所有单元格上工作 检查在不同单元格上选择时是否调用了 didselect。还要检查 profilepicarray 和 friendsnamearray 是否包含 indexPath.row 的值【参考方案3】:

您需要在ProfileViewController.h 上添加两个属性。

@property (nonatomic, assign) NSStirng* str;

@property (nonatomic, assign) UIImage* img;

ProfileViewController.m

@synthesize str;
@synthesize img;

在你的

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

if (!indexPath.row) 
    ProfileViewController *u = [[ProfileViewController alloc]init];

    u.str = [friendsnamearray objectAtIndex:indexPath.row];
    u.img = [UIImage imageNamed:[profilepicarray objectAtIndex:indexPath.row]];
    [self.navigationController pushViewController:u animated:YES];


而你的ProfileViewController 用作

self.img
self.str

希望对你有帮助。

【讨论】:

【参考方案4】:

使用您的didSelectRowAtIndexPath 传递值。

   - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    
        if (!indexPath.row) 
         
            //get selected image and label text  here.
           NSString *lbltxt=[friendsnamearray objectAtIndex:indexPath.row];
           UIImage *img=[friendsnamearray objectAtIndex:indexPath.row];

           //pass this two value into `NSUserDefaults` and get from  the `NSUserDefaults` to another viewcontroller

           [[NSUserDefaults standardUserDefaults] setObject:UIImagePNGRepresentation(img) forKey:key];
           [[NSUserDefaults standardUserDefaults] setObject:lbltxt forKey:@"preferenceName"];
           [[NSUserDefaults standardUserDefaults] synchronize];

            ProfileViewController *u = [[ProfileViewController alloc]init];
            [self.navigationController pushViewController:u animated:YES];
        
    

【讨论】:

【参考方案5】:

你还没有传递要在 "ProfileViewController" 中显示的数据,所以 VC 怎么知道要显示什么。

在导航到“ProfileViewController”之前,您需要传递要在下一个 VC 上显示的数据 您可以通过创建“ProfileViewController”对象来传递数据,从而通过对象本身访问其成员。 您可以访问和修改 ProfileViewController 类的成员,并使用它们在该类中显示数据。

【讨论】:

以上是关于IOS:通过 tableView 导航并在下一个视图中显示表视图数据的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin IOS 导航与 TableView

iOS11关于隐藏导航栏后带有tableView界面出现,下移问题

iOS滑动tableView来改变导航栏的颜色-1

Corona SDK 是不是适用于使用 tableview 导航的 iOS / Android 应用程序

tableview 没有用导航栏填满情节提要中的整个屏幕

iOS过滤tableview导航推送UIView,然后UIView返回导致crash