是否可以在 UITableViewCell 中添加 UITableView
Posted
技术标签:
【中文标题】是否可以在 UITableViewCell 中添加 UITableView【英文标题】:Is it possible to add UITableView within a UITableViewCell 【发布时间】:2013-06-28 04:41:44 【问题描述】:听到的只是我想实现这个的想法,
我想实现像书一样的页面,为此我想将 UITableView 和旋转 90 度及其单元格旋转 90 度,现在我想继承 UITableViewCell,现在在这个 tableview 单元格中可以添加 UITableview 所以该用户可以垂直滚动以查看内容,用户也可以水平滚动以转到旋转表格视图的下一个单元格。 只是我在想,有没有更好的方法来实现这个。
【问题讨论】:
您如何支持跨不同表视图重新排序? 【参考方案1】:是的,这是可能的,我在 UITableView 单元格中添加了 UITableVIew .. :)
无需在 xib 文件中添加 tableview 单元格 - 只需子类化 UITableviewCell 并使用下面的代码,将以编程方式创建一个单元格。
//in your main TableView
#import "ViewController.h"
#import "CustomCell.h"
@interface ViewController ()<UITableViewDataSource , UITableViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (void)dealloc
[_aTV release];
[super dealloc];
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return 3;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
CustomCell *cell = [self.aTV dequeueReusableCellWithIdentifier:@"Cell"];
if(cell == nil)
cell = [[[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]autorelease];
cell.dataAraay = [NSMutableArray arrayWithObjects:@"subMenu->1",@"subMenu->2",@"subMenu->3",@"subMenu->4",@"subMenu->5", nil];
return cell;
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
return 150;
//in your custom tableview cell
// .m file
#import "CustomCell.h"
@implementation CustomCell
@synthesize dataAraay; //array to hold submenu data
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
// Initialization code
self.frame = CGRectMake(0, 0, 300, 50);
UITableView *subMenuTableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain]; //create tableview a
subMenuTableView.tag = 100;
subMenuTableView.delegate = self;
subMenuTableView.dataSource = self;
[self addSubview:subMenuTableView]; // add it cell
[subMenuTableView release]; // for without ARC
return self;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
[super setSelected:selected animated:animated];
// Configure the view for the selected state
-(void)layoutSubviews
[super layoutSubviews];
UITableView *subMenuTableView =(UITableView *) [self viewWithTag:100];
subMenuTableView.frame = CGRectMake(0.2, 0.3, self.bounds.size.width-5, self.bounds.size.height-5);//set the frames for tableview
//manage datasource and delegate for submenu tableview
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return dataAraay.count;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
if(cell == nil)
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"]autorelease];
cell.textLabel.text = [self.dataAraay objectAtIndex:indexPath.row];
return cell;
@end
Swift 版本
在storyboard
中创建single view project
添加tableview
并设置其datasource
和delegate
将下面的代码粘贴到ViewController.swift
import UIKit
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate
override func viewDidLoad()
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 3;
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 1;
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
var cell:CustomCell? = tableView.dequeueReusableCellWithIdentifier("Cell") as? CustomCell
if cell == nil
cell = CustomCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
cell?.dataArr = ["subMenu->1","subMenu->2","subMenu->3","subMenu->4","subMenu->5"]
return cell!
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
return 150.0
创建一个新文件CustomCell.swift
,它是UITableViewCell
和do not select with xib
的子类,该文件没有.xib
文件table
,其cell
将像objective-c code
一样以编程方式创建。
将下面的代码粘贴到CustomCell.swift
import UIKit
class CustomCell: UITableViewCell,UITableViewDataSource,UITableViewDelegate
var dataArr:[String] = []
var subMenuTable:UITableView?
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style , reuseIdentifier: reuseIdentifier)
setUpTable()
required init(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
setUpTable()
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
setUpTable()
func setUpTable()
subMenuTable = UITableView(frame: CGRectZero, style:UITableViewStyle.Plain)
subMenuTable?.delegate = self
subMenuTable?.dataSource = self
self.addSubview(subMenuTable!)
override func layoutSubviews()
super.layoutSubviews()
subMenuTable?.frame = CGRectMake(0.2, 0.3, self.bounds.size.width-5, self.bounds.size.height-5)
override func setSelected(selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return dataArr.count
func numberOfSectionsInTableView(tableView: UITableView) -> Int
return 1
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
var cell: UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("cellID")
if cell == nil
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cellID")
cell?.textLabel?.text = dataArr[indexPath.row]
return cell!
【讨论】:
Hey Shan 如何将单元格内的表格视图委托给故事板? CustomCell 是否需要实现UITableViewDataSource
才能调用其cellForRowAtIndexPath
?
@MichaelOsofsky,是的,父单元格内的 tableview 需要确认委托和数据源,在上面的代码中,我通过 subMenuTableView.delegate = self
和 subMenuTableView.dataSource = self
以编程方式进行操作
@SurgePedroza 添加 swift 版本检查它
@Osa 您可以定义从自定义单元到视图控制器的自定义委托来处理点击操作【参考方案2】:
更好的方法:使用UIPageViewController
进行左/右页面滚动。每个页面都可以包含一个表格视图。
【讨论】:
【参考方案3】:虽然 rob 的想法更好,但它是可能的。检查方法:
取2个table view,给它们tag 1、2,我们把这些叫做kTagBaseTableView,kTagInnerTableView。现在下面是蓝图,如何使用两个表视图来处理,委托和数据源附加到单个视图控制器。
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView // Default is 1 if not implemented
switch (tableView.tag)
case kTagBaseTableView:
return baseSectionCount;
break;
case kTagInnerTableView:
return innerSectionCount;
break;
default:
break;
return 0;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
switch (tableView.tag)
case kTagBaseTableView:
return [baseDataSource count];
break;
case kTagInnerTableView:
return [innerDataSource count];
break;
default:
break;
return 0;
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = nil;
switch (tableView.tag)
case kTagBaseTableView:
static NSString* baseIdentifier = @"baseTableViewCell";
cell = [tableView dequeueReusableCellWithIdentifier:genderIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:genderIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.text = NSLocalizedString(titleKey, nil);
return cell;
break;
case kTagInnerTableView:
static NSString* innerIdentifier = @"innerTableViewCell";
cell = [tableView dequeueReusableCellWithIdentifier:genderIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:genderIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.text = NSLocalizedString(titleKey, nil);
return cell;
default:
break;
return cell;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section // fixed font style. use custom view (UILabel) if you want something different
switch (tableView.tag)
case kTagBaseTableView:
break;
case kTagInnerTableView:
break;
default:
break;
return nil;
//TABLE VIEW DELEGATE
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
selectedIndexPath = indexPath;
switch (tableView.tag)
case kTagBaseTableView:
break;
case kTagInnerTableView:
break;
default:
break;

[tableView deselectRowAtIndexPath:indexPath animated:YES];
【讨论】:
如果内表的内容依赖于外表,那么在处理kTagInnerTableView的case语句时,如何知道选择了外表的哪一行?【参考方案4】:为tableView创建一个子类并覆盖intrinsicContentSize。 I have answered here.
【讨论】:
【参考方案5】:#import "API.h"
#import "Parsing.pch"
#import "HomeViewController.h"
#import "ASIFormDataRequest.h"
#import "MBProgressHUD.h"
#import "UIImageView+WebCache.h"
#import "HomeCollectionViewCellForSubCat.h"
#import "CollectionViewTableViewCell.h"
#import "NewsTableViewCell.h"
#import "CategoryTableViewCell.h"
#import "HomeCollectionViewCellForSubCat.h"
#import "WebviewController.h"
#import "TopFreeAppsCollectionViewTableViewCell.h"
#import "TopSitesCollectionViewTableViewCell.h"
#import "TrandingVideoCollectionViewTableViewCell.h"
#import "SportsTableViewCell.h"
#import "JokesTableViewCell.h"
@interface HomeViewController ()
MBProgressHUD *hud;
NSMutableArray *Details;
NSIndexPath *IndexPath;
CollectionVIewTableViewCell *TrafficCell;
NewsTableViewCell *NewsCell;
CategoryTableViewCell *CategoryCell;
TopFreeAppsCollectionViewTableViewCell *TopAppsCell;
TopSitesCollectionViewTableViewCell *TopSitesCell;
TrandingVideoCollectionViewTableViewCell *TrendingVideosCell;
SportsTableViewCell *SportsCell;
JokesTableViewCell *JokesCell;
@end
NSString *More;
NSMutableArray *news;
@implementation HomeViewController
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.automaticallyAdjustsScrollViewInsets = NO;
//[self.navigationController setNavigationBarHidden:YES];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
return dataArray.count;
- (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"Traffic" ])
if(!TrafficCell)
TrafficCell = [tableView dequeueReusableCellWithIdentifier:@"CollectionVIewTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
TrafficCell.Traffic = [dict valueForKey:@"detail"];
[TrafficCell.collectionView reloadData];
return TrafficCell;
return TrafficCell;
else if([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"News"])
if(!NewsCell)
NewsTableViewCell *cell = (NewsTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"NewsTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
cell.News = [dict valueForKey:@"detail"];
[cell.NewsTableView reloadData];
return cell;
return NewsCell;
else if ([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"TopApps"])
if(!TopAppsCell)
TopAppsCell = [tableView dequeueReusableCellWithIdentifier:@"TopFreeAppsCollectionViewTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
TopAppsCell.TopApps = [[dict valueForKey:@"detail"]valueForKey:@"small_banner"];
[TopAppsCell.TopAppsCollectionView reloadData];
return TopAppsCell;
return TopAppsCell;
else if ([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"TopSites"])
if(!TopSitesCell)
TopSitesCell = [tableView dequeueReusableCellWithIdentifier:@"TopSitesCollectionViewTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
TopSitesCell.TopSites = [dict valueForKey:@"detail"];
[TopSitesCell.TopSitesCollectionView reloadData];
return TopSitesCell;
return TopSitesCell;
else if ([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"Category"])
if(!CategoryCell)
CategoryCell= [tableView dequeueReusableCellWithIdentifier:@"CategoryTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
CategoryCell.Category = [dict valueForKey:@"detail"];
[CategoryCell.CategorycollectionView reloadData];
return CategoryCell;
return CategoryCell;
else if ([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"TrendingVideos"])
if(!TrendingVideosCell)
TrendingVideosCell= [tableView dequeueReusableCellWithIdentifier:@"TrandingVideoCollectionViewTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
TrendingVideosCell.TrendingVideos = [[dict valueForKey:@"detail"]valueForKey:@"small_banner"];
[TrendingVideosCell.VideosCollectionView reloadData];
return TrendingVideosCell;
return TrendingVideosCell;
else if ([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"Sports"])
if(!SportsCell)
SportsCell= [tableView dequeueReusableCellWithIdentifier:@"SportsTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
SportsCell.Sports = [dict valueForKey:@"detail"];
[SportsCell.SportsTableView reloadData];
return SportsCell;
return SportsCell;
else if ([[dataArray[indexPath.row] valueForKey:@"type"] isEqual:@"Jokes"])
if(!JokesCell)
JokesCell= [tableView dequeueReusableCellWithIdentifier:@"JokesTableViewCell" forIndexPath:indexPath];
NSDictionary *dict=dataArray[indexPath.row];
JokesCell.Jokes = [dict valueForKey:@"detail"];
[JokesCell.JokesTableView reloadData];
return JokesCell;
return JokesCell;
else
return nil;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary *dict = dataArray[indexPath.row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
if([dict[@"type"] isEqual:@"Traffic" ])
//Find your collectionView in cell
//Tap on Traffic cells
else if([dict[@"type"] isEqual:@"News"])
//Tap on News cells
else if([dict[@"type"] isEqual:@"Category"])
//Tap on Category cells
else if([dict[@"type"] isEqual:@"TopApps"])
//Tap on TopApps cells
else if([dict[@"type"] isEqual:@"TopSites"])
//Tap on TopSites cells
else if([dict[@"type"] isEqual:@"TrendingVideos"])
//Tap on Trending cells
else if([dict[@"type"] isEqual:@"Sports"])
//Tap on Sports cells
else if([dict[@"type"] isEqual:@"Jokes"])
//Tap on Jokes cells
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary *dict = dataArray[indexPath.row];
if([dict[@"type"] isEqual:@"Traffic" ])
return 155;
else if([dict[@"type"] isEqual:@"News"])
return 300;
else if([dict[@"type"] isEqual:@"Category"])
return 120;
else if([dict[@"type"] isEqual:@"TopApps"])
return 180;
else if([dict[@"type"] isEqual:@"TopSites"])
return 240;
else if([dict[@"type"] isEqual:@"TrendingVideos"])
return 270;
else if([dict[@"type"] isEqual:@"Sports"])
return 310;
else if ([dict[@"type"] isEqual:@"Jokes"])
return 280;
return 200;
【讨论】:
以上是关于是否可以在 UITableViewCell 中添加 UITableView的主要内容,如果未能解决你的问题,请参考以下文章
是否不可能将子视图添加到我的 UITableViewCell 的 contentView 并使其宽度与 contentView 相等?
更改 UITableViewCell 中某些子视图的突出显示