是否可以在 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并设置其datasourcedelegate

将下面的代码粘贴到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,它是UITableViewCelldo 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 = selfsubMenuTableView.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 放置事件

在滚动 UITableViewCell 添加按钮图像问题

更改 UITableViewCell 中某些子视图的突出显示

是否可以在 UITableViewCell 和 UICollectionViewCell 之间共享 xib?

是否可以以编程方式在 UITableViewCell 上显示红色删除按钮?