【问题标题】:Creating a UITableView Programmatically以编程方式创建 UITableView
【发布时间】:2013-03-28 14:56:54
【问题描述】:

我在 Xcode 4.6 中有一个使用情节提要的应用程序。我向视图控制器类添加了一个 UITableView,它按预期工作。但是,当我尝试删除情节提要中的 UITableView 并以编程方式将其添加回同一个类时,我遇到了两个具体问题:

1)虽然我将 UITableViewCell 类型设置为 subtitle 类型,但是细节标签不再出现。

2)我选择单元格时应该发生的segue没有发生,甚至没有调用prepare segue,表明选择单元格时没有向表格视图发送消息。强>

以下是相关代码:

@interface StatsTableViewController () <UITableViewDataSource, UITableViewDelegate>
@property (strong, nonatomic) UITableView *tableView;

@end

@implementation StatsTableViewController

-(UITableView *)makeTableView
{
    CGFloat x = 0;
    CGFloat y = 50;
    CGFloat width = self.view.frame.size.width;
    CGFloat height = self.view.frame.size.height - 50;
    CGRect tableFrame = CGRectMake(x, y, width, height);

    UITableView *tableView = [[UITableView alloc]initWithFrame:tableFrame style:UITableViewStylePlain];

    tableView.rowHeight = 45;
    tableView.sectionFooterHeight = 22;
    tableView.sectionHeaderHeight = 22;
    tableView.scrollEnabled = YES;
    tableView.showsVerticalScrollIndicator = YES;
    tableView.userInteractionEnabled = YES;
    tableView.bounces = YES;

    tableView.delegate = self;
    tableView.dataSource = self;

    return tableView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView = [self makeTableView];
    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"newFriendCell"];
    [self.view addSubview:self.tableView];
}

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

    if (cell == nil) 
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    Friend *friend = [self.fetchedResultsController objectAtIndexPath:indexPath];

     **//THIS DATA APPEARS**
    cell.textLabel.text = friend.name;
    cell.textLabel.font = [cell.textLabel.font fontWithSize:20];
    cell.imageView.image = [UIImage imageNamed:@"icon57x57"];

    **//THIS DATA DOES NOT APPEAR**
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%i Games", friend.gameCount];
    cell.detailTextLabel.textColor = [UIColor lightGrayColor];

    return cell;
}

 -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"detailsView" sender:self];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
      //I set the segue identifier in the interface builder
     if ([segue.identifier isEqualToString:@"detailsView"])
     {

         NSLog(@"segue"); //check to see if method is called, it is NOT called upon cell touch

         NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
         ///more code to prepare next view controller....
     }
}

我不确定自己忘记做什么才能解决这两个问题。任何帮助表示赞赏。

【问题讨论】:

  • 尝试定义单元格的高度。
  • 行高不是单元格的高度吗?我把它设置为 45,这应该是足够的空间......
  • 哦,可以,我认为你定义了一个错误的方法 didDeselect 而应该是 didSelect。

标签: ios objective-c xcode uitableview


【解决方案1】:

当您注册一个类并使用 dequeueReusableCellWithIdentifier:forIndexPath: 时,dequeue 方法保证返回一个单元格,因此永远不会输入您的 if (cell == nil) 子句。所以,就照旧做,不要注册类,使用dequeueReusableCellWithIdentifier:

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

    if (cell == nil) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
//etc.
return cell;
}

至于转场,它不能被调用,因为你不能对你在代码中创建的表进行转场,而不是在 IB 中。再次,回到旧方法并使用 tableView:didSelectRowAtIndexPath: 当您选择一个单元格时将调用它。在那里实例化您的细节控制器并在代码中进行转换。

修改后:

我没有在那里看到您添加的代码。您已经实现了 didDeselectRowAtIndexPath 而不是 didSelectRowAtIndexPath。如果你改变它,你的 segue 应该可以工作。

【讨论】:

  • 我认为如果你的故事板中存在 segue,你可以使用它,但你仍然需要实现 tableView:didSelectRowAtIndexPath: 并以编程方式执行 segue,这违背了目的。
  • @tapi,是的,我知道,我没有看到她的一些代码,并认为 OP 试图直接从单元格中进行转场。
  • 我刚刚尝试添加 tableView:didSelectRowAtIndexPath: 并在正文中 performSegueWithIdentifier... 但这不起作用。我想我会尝试在代码中进行转换
  • @user1697845,它应该可以工作——你确定你在 IB 和代码中的 segue 名称相同吗?
  • @user1697845,为什么当您在 IB 中拥有表格视图时,您将其删除并在代码中重做?只是好奇。
【解决方案2】:

你可能会做到 100% 。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // init table view
    tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];

    // must set delegate & dataSource, otherwise the the table will be empty and not responsive
    tableView.delegate = self;
    tableView.dataSource = self;

    tableView.backgroundColor = [UIColor cyanColor];

    // add to canvas
    [self.view addSubview:tableView];
}

#pragma mark - UITableViewDataSource
// number of section(s), now I assume there is only 1 section
- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView
{
    return 1;
}

// number of row in the section, I assume there is only 1 row
- (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

// the cell will be returned to the tableView
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"HistoryCell";

    // Similar to UITableViewCell, but 
    JSCustomCell *cell = (JSCustomCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[JSCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    // Just want to test, so I hardcode the data
    cell.descriptionLabel.text = @"Testing";

    return cell;
}

#pragma mark - UITableViewDelegate
// when user tap the row, what action you want to perform
- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"selected %d row", indexPath.row);
}

@end

【讨论】:

    【解决方案3】:
    - (void)viewDidLoad {
         [super viewDidLoad];
         arr=[[NSArray alloc]initWithObjects:@"ABC",@"XYZ", nil];
         tableview = [[UITableView alloc]initWithFrame:tableFrame style:UITableViewStylePlain];   
         tableview.delegate = self;
         tableview.dataSource = self;
         [self.view addSubview:tableview];
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return arr.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
    
        if(cell == nil)
        {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MyCell"];
        }
    
        cell.textLabel.text=[arr objectAtIndex:indexPath.row];
    
        return cell;
    }
    

    【讨论】:

      【解决方案4】:
      - (void)viewDidLoad
      {
          [super viewDidLoad];
          tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
          tableView.delegate = self;
          tableView.dataSource = self;
      
          tableView.backgroundColor = [UIColor grayColor];
      
          // add to superview
          [self.view addSubview:tableView];
      }
      
      #pragma mark - UITableViewDataSource
      - (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView
      {
          return 1;
      }
      
      - (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:    (NSInteger)section
      {
          return 1;
      }
      
      // the cell will be returned to the tableView
      - (UITableViewCell *)tableView:(UITableView *)theTableView  cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          static NSString *cellIdentifier = @"HistoryCell";
      
          // Similar to UITableViewCell, but 
          UITableViewCell *cell = (UITableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
          if (cell == nil)
          {
              cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
          }
          cell.descriptionLabel.text = @"Testing";
          return cell;
      }
      

      【讨论】:

        【解决方案5】:

        样本表

         #import "StartreserveViewController.h"
         #import "CollectionViewController.h"
         #import "TableViewCell1.h"
        @interface StartreserveViewController ()
        
        
        {
        NSArray *name;
        NSArray *images;
        NSInteger selectindex;
        
        }
        
        @end
        
        @implementation StartreserveViewController
        
        - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = [UIColor blueColor];
        _startReservetable.backgroundColor = [UIColor blueColor];
        
        
        name = [[NSArray alloc]initWithObjects:@"Mobiles",@"Costumes",@"Shoes", 
        nil];
        images = [[NSArray 
         alloc]initWithObjects:@"mobilestitle.jpg",@"costumetitle.jpeg", 
         @"shoestitle.png",nil];
        
        
        
          }
        
         - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
        }
        

        pragma mark - UiTableview 数据源

         -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
         {
        return 1;
         }
        
         -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
         (NSInteger)section
         {
        return 3;
         }
        
         - (UITableViewCell *)tableView:(UITableView *)tableView 
          cellForRowAtIndexPath:(NSIndexPath *)indexPath
         {
        
        
        static NSString *cellId = @"tableview";
        
        TableViewCell1  *cell =[tableView dequeueReusableCellWithIdentifier:cellId];
        
        
        cell.cellTxt .text = [name objectAtIndex:indexPath.row];
        
        cell.cellImg.image = [UIImage imageNamed:[images 
        objectAtIndex:indexPath.row]];
        
        return cell;
        
        
        
         }
        
        
        -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
        (NSIndexPath *)indexPath
         {
        selectindex = indexPath.row;
        [self performSegueWithIdentifier:@"second" sender:self];
        }
        
        
        
           #pragma mark - Navigation
        
         // In a storyboard-based application, you will often want to do a little     
        - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
        
        if ([segue.identifier isEqualToString:@"second"])
        
          {
            CollectionViewController *obj = segue.destinationViewController;
                   obj.receivename = [name objectAtIndex:selectindex];
        
          }
        
        
        
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
        }
        
         @end
        

        .h

        #import <UIKit/UIKit.h>
        
        @interface StartreserveViewController :      
        UIViewController<UITableViewDelegate,UITableViewDataSource>    
        @property (strong, nonatomic) IBOutlet UITableView *startReservetable;
        
         @end
        

        【讨论】:

        【解决方案6】:

        vc.m

        #import "ViewController.h"
        

        导入“secondViewController.h”

         @interface ViewController ()
         {
        
        NSArray *cityArray;
        NSArray *citySubTitleArray;
        NSArray *cityImage;
        NSInteger selectindexpath;
        
        }
        @end
        
         @implementation ViewController
        
         - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        cityArray = [[NSArray 
        alloc]initWithObjects:@"Coimbatore",@"Salem",@"Chennai",nil];
        
        citySubTitleArray = [[NSArray alloc]initWithObjects:@"1",@"2",@"3", nil];
        cityImage = [[NSArray alloc]initWithObjects:@"12-300x272.png"
         , @"380267_70d232fc33b44d4ebe7b42bbe63ee9be.png",@"apple-logo_318
         -40184.png", nil];
        
         }
        
        
         #pragma mark - UITableView Data Source
        
         - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
         {
        return 1;
        
         }
        
         - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection 
         :(NSInteger)section
          {
        return cityImage.count;
         }
        
        - (UITableViewCell *)tableView:(UITableView *)tableView 
        cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
        static NSString *cellId = @"city";
        
        UITableViewCell *cell =
         [tableView dequeueReusableCellWithIdentifier:cellId];
        
        if (cell == nil)
        {
            cell = [[UITableViewCell 
          alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellId];
        }
        
        cell.textLabel.text = [cityArray objectAtIndex:indexPath.row];
        cell.detailTextLabel.text = [citySubTitleArray objectAtIndex:indexPath.row];
        cell.imageView.image = [UIImage imageNamed:
         [cityImage objectAtIndex:indexPath.row]];
        
        
        
        
         //    NSData *data = [[NSData alloc]initWithContentsOfURL:
         [NSURL URLWithString:@""]];
        
         //    cell.imageView.image = [UIImage imageWithData:data];
        
        return cell;
        }
        
        -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath
        :  (NSIndexPath *)indexPath
         {
         NSLog(@"---- %@",[cityArray objectAtIndex:indexPath.row]);
         NSLog(@"----- %@",[cityImage objectAtIndex:indexPath.row]);
         selectindexpath=indexPath.row;
         [self performSegueWithIdentifier:@"second" sender:self];
          }
        
          #pragma mark - Navigation
        
         // In a storyboard-based application, you will often want to do a little p
         - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
            {
         // Get the new view controller using [segue destinationViewController].
         // Pass the selected object to the new view controller.
         if ([segue.identifier isEqualToString:@"second"])
         {
            secondViewController *object=segue.destinationViewController;
            object.cityName=[cityArray objectAtIndex:selectindexpath];
            object.cityImage=[cityImage objectAtIndex:selectindexpath];
               }
         }
        
        
        - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
         }
        
         @end
        

        vc.m

         #import <UIKit/UIKit.h>
        
         @interface ViewController : UIViewController<UITableViewDataSource
          , UITableViewDelegate>
         @property (strong, nonatomic) IBOutlet UITableView *cityLabelList;
        
        @end
        

        sv.m

         #import <UIKit/UIKit.h>
        
        @interface secondViewController : UIViewController
        @property(strong, nonatomic) NSString *cityName;
         @property(strong,nonatomic)NSString *cityImage;
        @end
        

        sv.h

        #import "secondViewController.h"
        
         @interface secondViewController ()
        
         @property (strong, nonatomic) IBOutlet UILabel *lbl_desc;
         @property (strong, nonatomic) IBOutlet UIImageView *img_city;
            @end
        
         @implementation secondViewController
        
         - (void)viewDidLoad {
         [super viewDidLoad];
        // Do any additional setup after loading the view.
        self.title=self.cityName;
        
        
        if ([self.cityName isEqualToString:@"Coimbatore"])
        {
        
        
            self.lbl_desc.text=@"Coimbatore city";
            self.img_city.image=[UIImage imageNamed:
            [NSString stringWithFormat:@"%@",self.cityImage]];
        }
         else if ([self.cityName isEqualToString:@"Chennai"])
         {
        
            self.lbl_desc.text= @"Chennai City Gangstar";
            self.img_city.image=[UIImage imageNamed:
           [NSString stringWithFormat:@"%@",self.cityImage]];
        
           }
          else
           {
        
        
            self.lbl_desc.text= @"selam City";
            self.img_city.image=[UIImage imageNamed:
           [NSString stringWithFormat:@"%@",self.cityImage]];
        
           }
         }
        
        - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
        }
        

        【讨论】:

          【解决方案7】:

          使用 tableViewController 创建一个表格视图。

          import UIKit
          
          class TableViewController: UITableViewController
          {
              let tableViewModel = TableViewModel()
              var product: [String] = []
              var price: [String] = []
              override func viewDidLoad()
              {
                  super.viewDidLoad()
                  self.tableView.contentInset = UIEdgeInsetsMake( 20, 20 , 0, 0)
                  let priceProductDetails = tableViewModel.dataProvider()
          
                  for (key, value) in priceProductDetails
                  {
                      product.append(key)
                      price.append(value)
                  }
              }
          
              override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
              {
                  return product.count
              }
          
              override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
              {
                  let cell = UITableViewCell(style: .Value1, reuseIdentifier: "UITableViewCell")
                  cell.textLabel?.text = product[indexPath.row]
                  cell.detailTextLabel?.text = price[indexPath.row]
                  return cell
              }
          
              override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
              {
                  print("You tapped cell number \(indexPath.row).")
              }
          }
          

          【讨论】:

            【解决方案8】:
            - (NSInteger)tableView:(UITableView *)theTableView numberOfRowsInSection:(NSInteger)section
            {
                return 1;
            }
            
            - (UITableViewCell *)tableView:(UITableView *)theTableView  cellForRowAtIndexPath:(NSIndexPath *)indexPath
            {
                static NSString *cellIdentifier = @"HistoryCell";
            
                UITableViewCell *cell = (UITableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
                if (cell == nil)
                {
                    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
                }
                cell.descriptionLabel.text = @"Testing";
                return cell;
            }
            
            - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
            {
                //Code for selection.
            }
            

            这些是 UITableView 委托方法。

            【讨论】:

            • 最好每次都被记住
            【解决方案9】:
            #import "ViewController.h"
            
            @interface ViewController ()
            
            {
            
                NSMutableArray *name;
            
            }
            
            @end
            
            
            - (void)viewDidLoad 
            
            {
            
                [super viewDidLoad];
                name=[[NSMutableArray alloc]init];
                [name addObject:@"ronak"];
                [name addObject:@"vibha"];
                [name addObject:@"shivani"];
                [name addObject:@"nidhi"];
                [name addObject:@"firdosh"];
                [name addObject:@"himani"];
            
                _tableview_outlet.delegate = self;
                _tableview_outlet.dataSource = self;
            
            }
            
            
            - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
            
            {
            
            return [name count];
            
            }
            
            
            - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
            
            {
            
                static NSString *simpleTableIdentifier = @"cell";
            
                UITableViewCell *cell = [tableView       dequeueReusableCellWithIdentifier:simpleTableIdentifier];
            
                if (cell == nil) {
                    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
                }
            
                cell.textLabel.text = [name objectAtIndex:indexPath.row];
                return cell;
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-02-25
              • 1970-01-01
              • 2017-03-06
              • 1970-01-01
              • 1970-01-01
              • 2011-06-08
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多