【问题标题】:How to create a UITableViewCell with a UISwitch and get the data?如何使用 UISwitch 创建 UITableViewCell 并获取数据?
【发布时间】:2011-06-02 22:03:12
【问题描述】:

我有一个简单的问题。我在 Interface Builder 中创建了一个包含 UISwitch 的自定义 UITableViewCell。

问题 1:更简单、更好的方法? 问题 2:在 UITableViewController 中使用时,获取数据的最佳方式是什么?在某些时候,我要么需要遍历表格并检查每个单元格的状态,要么在开关状态直接改变时发送一些反馈?

感谢您的帮助。

【问题讨论】:

    标签: iphone uitableview uiswitch


    【解决方案1】:

    两种选择:

    1) 使用指向数据模型的指针初始化单元格。让单元实现开关的委托回调。当开关更改时,使用指向数据模型的指针来反映新设置。或者,使用指向视图控制器的指针初始化单元格。让单元实现切换委托方法,然后使用适当的单元上下文信息回调到您的视图控制器。

    2) 让您的视图控制器实现切换委托回调。当开关改变时,确定它是哪个开关/单元格(可能必须将开关的“标记”属性设置为行号或其他东西)并在视图控制器的上下文中处理更新。

    【讨论】:

      【解决方案2】:

      您可以在附件视图中添加UISwitch。这是最简单的方法,更不用说它看起来“优雅”了。

      然后,在您的 tableview 控制器代码中,您可以在每次切换开关时调用选择器,甚至可以通过在控制器中获取开关的当前状态来切换开关本身。

      如果您需要代码示例,请告知。

      ---示例代码---

      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      
      static NSString *CellIdentifier = @"Cell";
      
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (cell == nil) {
          cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
          //add a switch
          UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
          cell.accessoryView = switchview;
          [switchview release];
      }
      
      cell.textLabel.text = [NSString stringWithFormat:@"%d", indexPath.row];
      
      return cell;
      }
      

      然后,您可以使用一种方法来根据模型中的更改更新开关。你可以使用任何你想要的东西——委托、通知、KVO 等等。

      例子:

      - (void)updateSwitchAtIndexPath:(NSIndexPath *)indexPath {
      UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
      UISwitch *switchView = (UISwitch *)cell.accessoryView;
      
      if ([switchView isOn]) {
          [switchView setOn:NO animated:YES];
      } else {
          [switchView setOn:YES animated:YES];
      }
      
       }
      

      【讨论】:

      • 我想知道您是否有关于用于 UISwitch 的 KVO 的示例。我尝试像UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero]; cell.accessoryView = switchview; [switchview addObserver:self forKeyPath:@"on" options:NSKeyValueChangeSetting context:NULL]; 一样实现,但是当 Switch 值更改时,我的函数 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ NSLog(@"observeValueForKeyPath"); } 没有被调用
      • 如果您有示例代码来获取调用函数中的 IndexPath?我也尝试像 [(UISwitch*)cell.accessoryView addTarget:self action:@selector(updateSwitchAtIndexPath:) forControlEvents:UIControlEventValueChanged]; 那样实现但我得到了一个 2012-02-20 11 :39:32.962 phoneApp [1935:f803] - [UISwitch row]:无法识别的选择器发送到实例0x6b56060 2012-02-20 11:39:32.963 phoneApp [1935:f803] ***由于未捕获的异常“NSInvalidArgumentException”而终止应用程序, 原因:'-[UISwitch row]: unrecognized selector sent to instance 0x6b56060'
      • 在这种情况下,我做了回调函数,如 - (void)updateSwitchAtIndexPath:(NSIndexPath *)indexPath
      • 请注意示例代码。除非表中的每个单元格都打算有一个开关,否则当单元格被重用时,您的代码将无法正常工作(因为单元格标识符始终是相同的 @"Cell")。如果您的 UITableView 有其他类型的单元格(没有 UISwitch),那么 dequeReusableCellWithIdentifier 可能会返回一个没有 UISwitch 的单元格,在这种情况下,该单元格将永远不会获得 UISwitch,因为您只在创建新单元格时添加一个(即当 cell == null 时) .对于需要 UISwitch 的索引路径,您应该使用唯一的 cellIdentifier,例如 @"SwitchCell"。
      • 错了! tableView:cellForRowAtIndexPath: 在表格视图创建/重用单元格时被调用。所以这个方法可能会返回现有对象和新对象(当然没有使用)。它不支持具有 2 种或更多不同单元格类型的表格
      【解决方案3】:

      谢谢。 我没有你的 indexPath,但你可以用这样的标签来识别单元格或对象:

      if (indexPath.row == 0) {
              cell.textLabel.text = @"Twitter";
      
      
              UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
              switchview.tag = 111;
              //switchview.selected = 0;
              cell.accessoryView = switchview;
      
              [switchview addTarget:self action:@selector(updateSwitchAtIndexPath) forControlEvents:UIControlEventTouchUpInside];
      
              //cell.accessoryType =UITableViewCellAccessoryDisclosureIndicator;
              //[switchview release];
      
          }
      
      
      - (void)updateSwitchAtIndexPath {
      
      for (UITableViewCell * cell in tblView.subviews) {
      
         for (UISwitch *swch in cell.subviews) {
      
      
               UISwitch *switchView = (UISwitch *)cell.accessoryView;
      
              if (switchView.tag == 111) {
      
                  if ([switchView isOn]) {
                       NSLog(@")>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ON");
                  }else{
                      NSLog(@")>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OFF");
                  }
      
              } 
      
                if (switchView.tag == 222) {
                  if ([switchView isOn]) {
                      NSLog(@")>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ON");
                  }else{
                      NSLog(@")>>>>>>>>>>>>>>>>>>>>>>>>>>>>> OFF");
                  }
      
              }
          }
      }
      

      }

      【讨论】:

      • 在配置 UITableViewCell 时,我们可以这样做 ..this With Tag ** [switchview addTarget:self action:@selector(updateSwitchAtIndexPath) forControlEvents:UIControlEventTouchUpInside];**
      【解决方案4】:
      Switch.tag = indexPath.row;
      [Switch addTarget:self action:@selector(updateSwitchAtIndexPath:) forControlEvents:UIControlEventTouchUpInside];
      
      
      
      - (void)updateSwitchAtIndexPath:(UISwitch *)aswitch{
          FFLog(@"%i",aswitch.tag);
      }
      

      【讨论】:

        【解决方案5】:

        要在 Swift 3 和 Swift 4 中获取 UISwitch 的值,您可以向其添加目标:

        func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: IndexPath) -> UITableViewCell {
        
            ...
        
            cell.uiSwitch.tag = 100
            cell.uiSwitch.addTarget(self, action: #selector(ViewController.switchAtValueChanged(switchFromTableViewCell:)), for: UIControlEvents.valueChanged)
        
            ...
        }
        

        你可以得到这样的值:

        @objc func switchAtValueChanged(uiSwitch: UISwitch) {
        
            if uiSwitch.tag == 100 {
                let value = uiSwitch.isOn
            }
        } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多