IOS:在我的项目中浏览tableView并在下一个视图中显示表格视图数据
我正在使用自定义UITableView
,其中我传递了2个数组(图像和名称)数组显示在UITableView
上。现在我想当我点击表格的任何单元格时,将显示UITableViewCell
的凭证,以显示在下一个视图中,其中我使用UIImageView
(用于图像)和UILabel(用于名称显示)。我还输入了我必须显示图像和名称的VC。 请建议我的代码到另一个视图中显示的名称和形象IOS:在我的项目中浏览tableView并在下一个视图中显示表格视图数据
我使用如下代码
.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];
}
}
对于像你这样的情况,我建议你继承表视图单元格。在您的案例中为配置文件图像和名称创建2个属性。覆盖这些属性的setter并根据需要设置视图组件。
在做了选择行的事件之后,您现在可以使用自定义单元格的相同属性,然后可以将其设置为目标控制器的属性。
但是,如果你想做到这一点,你应该总是使用模型类(MyUserClass),然后可以将它插入到自定义单元格和视图控制器中。这样,您只能为输入和输出保留一个属性。另外,如果您的模型类发生更改,或者您需要显示更多数据,那么代码的大部分内容都不会改变。例如,假设您的单元格保持不变,但在视图控制器上您还希望添加用户位置:您只需将位置属性添加到模型类,然后仅在视图控制器中使用它。 (如果您使用多个属性完成该操作,单元格将需要收集该属性,即使它没有显示它)。
让我给你一个关于通信与表视图,表视图单元格和所有者(通常是视图控制器)的一些使用的很好的例子。
这是如何很好地从单元中获取数据以及将自定义控件(按钮)挂钩到单元格并通过适当的数据通知事件所有者的显示。
请注意,这一切都是以编程方式完成的,因此您可以看到完成的所有代码。尽管如此,这可能全都是由故事板完成的。
页眉:
#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
创建性质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传递的值。让我知道它是否有效。谢谢 – Irfan
相同的结果不起作用 –
你需要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
希望它可以帮助你。
使用您的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];
}
}
您还没有传递的数据将被显示在 “ProfileViewController”,所以VC会怎么会知道显示什么。
在导航到“ProfileViewController”之前,您需要传递要在下一个VC上显示的数据。 您可以通过创建“ProfileViewController”对象来传递数据,从而通过对象本身访问其成员。 您可以访问和修改ProfileViewController类的成员,并使用它们来显示此类中的数据。
检查此... http://stackoverflow.com/questions/22759167/how-to-make-a-push-segue-when-a-uitableviewcell-is-selected –
我使用自定义tableview请告诉我在didSelectRow方法中做了什么更改 –