【问题标题】:Automatically adding UI elements to the UIStackView while UITable ScrollingUITable 滚动时自动将 UI 元素添加到 UIStackView
【发布时间】:2016-04-19 15:07:32
【问题描述】:

在我的应用程序中有一个 UITable。在表格单元格中,我添加了 UIStackView 以在加载表格单元格时填充。

在向下滚动表格之前工作正常,当我向上和向下滚动时,堆栈视图会添加更多元素。 (elements表示UIButtons,以后我会用UIlabel代替)

我没有任何想法来解决这个问题。谢谢。。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    UIStackView *stkItems=(UIStackView *)[cell viewWithTag:8];

    for(int i=0;i<5;i++)    {
        UIButton *btn=[UIButton buttonWithType:UIButtonTypeSystem];
        [btn setTitle:@"test btn" forState:UIControlStateNormal];
        [stkItems addArrangedSubview:btn];
    }
}

【问题讨论】:

    标签: ios objective-c uitableview uistackview


    【解决方案1】:

    表格视图在离开屏幕时重用单元格。这就是您发送名为dequeue<strong>Reusable</strong>CellWithIdentifier: 的消息的原因。您永远不会从堆栈视图中取出按钮。每次重用单元格时,您都会在堆栈视图中已经存在的按钮上再添加五个按钮。

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题,在表格视图单元格中添加了arrangedSubviews

      这里的诀窍是,在单元格的 prepareForResue 中,使用 removeFromSuperview 从其父视图中删除 stackView 的每个子视图,然后调用 removeArrangedSubview

      应该是这样的:

      for view in self.views {
          radioView.removeFromSuperview()
      }
      self.views.removeAll()
      
      for arrangedSubview in self.stackView.arrangedSubviews {
          self.stackView.removeArrangedSubview(arrangedSubview)
      }
      

      正如Apple documentation 所说:

      [removeArrangedSubview] 方法不会移除提供的视图 从堆栈的子视图数组;因此,观点仍然 显示为视图层次结构的一部分。

      希望对某人有所帮助;)

      【讨论】:

        【解决方案3】:

        从该代码看来,每次您的应用需要绘制一个单元格时,它都会向 UIStackView 添加按钮,因此当一个单元格被重用时(通过 dequeueReusableCellWithIdentifier),它仍然包含按钮,但您的代码会不断添加更多按钮时间。也许您应该检查 UIStackView 是否有足够的按钮或清除所有按钮并添加您需要的内容。

        希望对你有帮助

        【讨论】:

        • 是的,这就是我的想法,但是如何清除 stackView 中的子视图。
        • 您应该遍历 UIStackView 的 subviews 属性并调用 UIStackView (developer.apple.com/library/ios/documentation/UIKit/Reference/…) 的 removeArrangedSubview 和 UIButton 的 removeFromSuperview (developer.apple.com/library/ios/documentation/UIKit/Reference/…),或者堆栈视图中的任何控件
        • 你的意思是在我得到堆栈视图之后添加这条线。 [[stkItems 子视图]makeObjectsPerformSelector:@selector(removeFromSuperview)];它不工作..
        • 根据文档,您应该调用 both 函数To prevent the view from appearing on screen after calling the stack’s removeArrangedSubview: method, explicitly remove the view from the subviews array by calling the view’s removeFromSuperview method, or set the view’s hidden property to YES.
        【解决方案4】:

        我想我解决了。但我不知道它是否符合标准。

        这是更新的。 我已经初始化并将其声明为 0。

        @implementation HistoryViewController
        int data=0; 
        

        并像这样更改 cellForRowAtIndexPath,这样它就不会再次更新相同的堆栈视图

        -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
        {
            NSLog(@"%ld",indexPath.row);
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        
        
            if(data <=indexPath.row)
            {
                data=(int)indexPath.row;
                UIStackView *stkItems=(UIStackView *)[cell viewWithTag:8];
                [stkItems.subviews makeObjectsPerformSelector: @selector(removeFromSuperview)];
                for(int i=0;i<5;i++)    {
                    UIButton *btn=[UIButton buttonWithType:UIButtonTypeSystem];
                    [btn setTitle:@"test btn" forState:UIControlStateNormal];
                    [stkItems addArrangedSubview:btn];
                }
            }
        
        
        
            return cell;
        }
        

        【讨论】:

          【解决方案5】:

          由于单元格正在重用 UIStackView,因此您必须在添加新子视图之前删除所有子视图。为此,只需在循环之前调用以下代码并将排列好的子视图添加到 UIStackView:

          斯威夫特 3

          for view in stackView.arrangedSubviews {
              view.removeFromSuperview()
          }
          

          Objective-C

          for (UIView *view in stackView.arrangedSubviews) {
              [view removeFromSuperview];
          }
          

          *注意:如果您根据 Apple 的 cmets 调用 [stackView removeArrangedSubview:view],它实际上并没有从接收器中完全删除它。请参阅下面的报价:

          - (void)removeArrangedSubview:(UIView *)view "从排列的子视图列表中删除一个子视图,而不将其删除为 接收器的子视图。 要将视图作为子视图删除,请照常发送 -removeFromSuperview ; 相关的 UIStackView 会将其从其排列的Subviews 列表中删除 自动。”

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-08-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-03-14
            • 2018-11-09
            • 2023-03-28
            • 1970-01-01
            相关资源
            最近更新 更多