【问题标题】:Programmatically get the custom UIViews embedded inside UIStackView以编程方式获取嵌入在 UIStackView 中的自定义 UIView
【发布时间】:2019-05-03 05:41:21
【问题描述】:

在我的 ViewController 中,我有 12 个自定义 UIViews(命名为 CardView)。

我正在尝试以编程方式遍历ViewController 的子视图以找到自定义视图(CardView)并进行一些配置。以下是我计算 CardView 数量的代码。

    private func cardCount()->Int{
            var count = 0
            for subview in self.view.subviews{
                if subview is CardView{
                    count = count + 1
                }
            }
            return count
    }

但是,它返回“0”,原因是我的观点嵌入在 UIStackViews 中。我在一个垂直对齐的视图中有 3 个水平对齐的堆栈视图-

如何以编程方式获取我的 CardViews。任何帮助,将不胜感激。

【问题讨论】:

  • 使用属性排列子视图而不是子视图
  • 您可以将collectionView用于这种UI。这是更好的方法
  • 亲爱的,我认为您可以一次又一次地循环访问卡片视图
  • 第一个循环用于垂直堆栈视图,第二个用于水平堆栈视图,最后一个用于访问卡片
  • 我认为,您应该通过使用集合视图项内的堆栈视图或表格视图单元格来更改此处的 ui 呈现逻辑。但是为了在这里回答您的查询,您可以创建容器stack view 的实例并迭代子stack views。这样,您将获得个人stack views,第二次迭代将针对个人stack views,以获得subviews。

标签: ios swift uiview uiviewcontroller uistackview


【解决方案1】:

你可以先做一些平面地图来扁平化你的视图结构,然后再计算它们:

private func cardCount()->Int{

    var count = 0
    for subview in self.view.subviews.flatMap { $0.subviews }.flatMap { $0.subviews }{
        if subview is CardView{
            count = count + 1
        }
    }
    return count

}

但我觉得你做错了事。卡的数量听起来像是您模型中的内容。您应该有一个名为cardCount 的变量,并且屏幕上的卡片应该根据该变量而改变,而不是相反。

【讨论】:

    【解决方案2】:

    您为每个水平堆栈视图创建 IBOutlets。然后循环遍历stackviews中的子视图。

    @IBOutlet weak var StackView1: UIStackView!
    @IBOutlet weak var StackView2: UIStackView!
    @IBOutlet weak var StackView3: UIStackView!
    
    
    
      for customView in StackView1.arrangedSubviews
      {
         // Do task
      }
    

    【讨论】:

      【解决方案3】:

      试试这个

      private func cardCount() -> Int
      {
          var count = 0
          for subview in self.view.subviews
          {
              if let stackView: UIStackView = subview as? UIStackView
              {
                  let arrangedViews = stackView.arrangedSubviews
                  for cardView in arrangedViews
                  {
                      if cardView is CardView
                      {
                          count = count + 1
                      }
                  }
      
              }
          }
          return count
      }
      

      【讨论】:

        【解决方案4】:

        从您分享的图示来看,StackView 似乎是第一个孩子。每当您获得子视图时,只会返回第一个子视图。所以self.view.subviews 只会产生一个UIStackView。给每个堆栈视图一个标签。然后,在代码中:

        private func cardCount()->Int{
                var count = 0
                for subview in self.view.subviews{
                    if subview.tag == 10 {  // parent stack view
                         for subviewStack in subview {  // Get subviews of parent stackview
                              if subviewStack.tag == 11 {  // First stack view child
                                  for subViewSubStack in subviewStack.subviews { // Get card views in this stack view
                                      // Apply your count logic 
                                  }
                              }
                         }
        
                    }
                }
                return count
        }  
        

        我只写了第一个条件。您可以添加其他人。
        说了这么多,我不会说这是最优化的解决方案。这可以而且应该被重构。

        【讨论】:

        • @Sweeper 的解决方案是我所写内容的重构版本。
        【解决方案5】:

        像这样创建一个扩展方法。它将计算视图控制器中的所有 CardView 实例。

        extension UIView {
            func cardCount() -> Int {
                switch self {
                case let self as CardView:
                    return 1
                case let self as UIStackView:
                    return self.arrangedSubviews.reduce(0, { $0 + $1.cardCount() })
                default:
                    return self.subviews.reduce(0, { $0 + $1.cardCount() })
                }
            }
        }
        

        并在viewDidLoad中调用此方法

        class ViewControllerd: UIViewController {
            override func viewDidLoad() {
                super.viewDidLoad()
                print(self.view.cardCount())
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-14
          • 2011-11-11
          • 1970-01-01
          • 2016-07-31
          • 2015-05-25
          • 2020-10-16
          相关资源
          最近更新 更多