简体   繁体   English

以编程方式获取自定义UIView嵌入UIStackView中

[英]Programmatically get the custom UIViews embedded inside UIStackView

In my ViewController , I have 12 custom UIViews (named CardView). 在我ViewController ,我有12个自定义UIViews (名为CardView)。

在此处输入图片说明

I am trying to iterate through the subviews of the ViewController programmatically to find the custom view(CardView) and do some configuration. 我试图以编程方式遍历ViewController的子视图以找到自定义视图(CardView)并进行一些配置。 Following is my code to count the number of CardViews. 以下是我的代码来计算CardViews的数量。

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

However, it is returning me '0' and the reason being my views are embedded inside UIStackViews . 但是,它返回我“ 0”,原因是我的视图已嵌入UIStackViews I have 3 horizontally aligned stack views inside a vertically aligned one like- 我在一个垂直对齐的像里面有3个水平对齐的堆栈视图-

在此处输入图片说明

How can I get my CardViews programmatically. 如何以编程方式获取CardViews。 Any help would be appreciated. 任何帮助,将不胜感激。

You can do a few flat maps to flatten your view structure first, then count them: 您可以先做一些平面地图来展平您的视图结构,然后对它们进行计数:

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

}

But I feel like you are doing things the wrong way around. 但是我觉得您做事的方式是错误的。 The number of cards sounds like something in your model. 卡的数量听起来像模型中的东西。 You should have a variable called cardCount and the cards on the screen are supposed to change according to that variable, not the other way around. 您应该有一个名为cardCount的变量,并且屏幕上的卡片应该根据该变量进行更改,而不是相反。

You create IBOutlets to each of the horizontal stack views. 您为每个水平堆栈视图创建IBOutlet。 Then loop through the subviews in the stackviews. 然后循环遍历stackviews中的子视图。

@IBOutlet weak var StackView1: UIStackView!
@IBOutlet weak var StackView2: UIStackView!
@IBOutlet weak var StackView3: UIStackView!



  for customView in StackView1.arrangedSubviews
  {
     // Do task
  }

Try this 尝试这个

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
}

From the pictorial diagram you shared, it seems the StackView is the first child. 从您共享的图片图中,似乎StackView是第一个孩子。 Whenever you get the subviews, only the first child views are returned. 每当您获得子视图时,仅返回第一个子视图。 So self.view.subviews would result in only one UIStackView . 因此self.view.subviews将只产生一个UIStackView Give a tag to each stack view. 给每个堆栈视图添加一个标签。 Then, in code : 然后,在代码中:

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
}  

I have written only the first condition. 我只写了第一个条件。 You might add others. 您可以添加其他人。
Having said this, I won't say this is the most optimum solution. 话虽如此,我不会说这是最佳的解决方案。 This can and should be refactored. 这可以并且应该重构。

Create an extension method like this. 创建这样的扩展方法。 It will count all CardView instances in the view controller. 它将计算视图控制器中的所有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() })
        }
    }
}

and call this method in viewDidLoad 并在viewDidLoad调用此方法

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在UITableView内以编程方式将UIViews添加到UIStackView - Add UIViews to UIStackView programmatically inside UITableView 用UIViews编程填充的UIStackView不在UIScrollView内滚动 - UIStackView programmatically filled with UIViews doesn't scroll inside UIScrollView 如何以编程方式在 UIStackView 中添加响应式 UIPageViewController? - How to add a responsive UIPageViewController inside an UIStackView programmatically? UIStackView内嵌的UIStackView对齐方式 - UIStackView embedded within UIStackView alignment 如何在UIStackView中堆叠自定义视图 - How to stack custom views inside a UIStackView 如何以编程方式在UITableViewCell swift中为UIStackView添加约束? - How to add constraints to UIStackView inside of a UITableViewCell swift programmatically? 以编程方式将由Interface Builder安排的自定义UIView替换为UILabels - Replace custom UIViews arranged by Interface Builder with UILabels programmatically 以编程方式从XIB向UIStackView添加了一堆自定义视图 - programmatically add a bunch of custom view from XIB to UIStackView iOS UIStackView分别更改UIViews的间距 - iOS UIStackView individually changing the spacing of UIViews 如何使用自定义 UIViews(和内部转换)重新加载自定义 UICollectionViewCell - How to reload custom UICollectionViewCell`s with custom UIViews (and transitions inside)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM