【问题标题】:Want to push to another view controller from a container view想要从容器视图推送到另一个视图控制器
【发布时间】:2017-10-02 09:38:22
【问题描述】:

我有什么:带有一些“子/容器”视图的视图控制器 (WhereViewController)。一种是集合视图(typeCollectionView)。 WhereViewController 嵌入在 navigationController 中: Screenshot

class WhereViewController: UIViewController {

lazy var progressContainerView: ProgressBarView = {
    let containerView = ProgressBarView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))

    containerView.translatesAutoresizingMaskIntoConstraints = false

    return containerView
}()

let questionLabel: UILabel = {
    let label = UILabel()

    label.text = "question?"
    label.textAlignment = NSTextAlignment.center
    label.font = UIFont.init(name: "OpenSans-Italic", size: 14)
    label.textColor = UIColor(red:0.33, green:0.33, blue:0.33, alpha:1.0)
    label.translatesAutoresizingMaskIntoConstraints = false

    return label
}()

let typeCollectionView: WhereCollectionView = {
    let collectionView = WhereCollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))

    collectionView.translatesAutoresizingMaskIntoConstraints = false

    return collectionView
}()

override func viewDidLoad() {
    super.viewDidLoad()

    navigationItem.title = "Schaden melden"

    view.backgroundColor = UIColor.white


    view.addSubview(progressContainerView)
    view.addSubview(questionLabel)
    view.addSubview(typeCollectionView)

    setupProgressContainerView()
    setupQuestionLabel()
    setupTypeCollectionView()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

private func setupProgressContainerView() {
    progressContainerView.topAnchor.constraint(equalTo: view.topAnchor, constant: 60).isActive = true
    progressContainerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    progressContainerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    progressContainerView.heightAnchor.constraint(equalToConstant: 50).isActive = true
}

private func setupQuestionLabel() {
    questionLabel.topAnchor.constraint(equalTo: progressContainerView.bottomAnchor, constant: 22).isActive = true
    questionLabel.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    questionLabel.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    questionLabel.heightAnchor.constraint(equalToConstant: 20).isActive = true
}

private func setupTypeCollectionView() {
    typeCollectionView.topAnchor.constraint(equalTo: questionLabel.bottomAnchor, constant: 20).isActive = true
    typeCollectionView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    typeCollectionView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    typeCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}

}

我想要做什么: 在 typeCollectionView 中:如果选择了一个项目 (didSelectItemAt),我想通过 WhereViewController 的 navigationController 推送到下一个 viewController。我的 typeCollectionView 看起来像:

class WhereCollectionView: UICollectionView, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

var whereViewController: WhereViewController?

let label = ["x", "y", "z"]

override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
    let layout = UICollectionViewFlowLayout()
    super.init(frame: CGRect.zero, collectionViewLayout: layout)

    backgroundColor = UIColor.white

    delegate = self
    dataSource = self

    self.register(WhereCollectionViewCell.self, forCellWithReuseIdentifier: "WhereCollectionViewCell")
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}


func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of items
    return label.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "WhereCollectionViewCell", for: indexPath) as! WhereCollectionViewCell

    cell.injureLabel.text = label[indexPath.row]

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: self.frame.width, height: 75)
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

}

}

我已经尝试将 whereViewController 赋予 typeCollectionView:

let typeCollectionView: WhereCollectionView = {
    let collectionView = WhereCollectionView(frame: CGRect(x: 0, y: 0, width: 0, height: 0))

    collectionView.translatesAutoresizingMaskIntoConstraints = false
    collectionView.whereViewController = self 

    return tableView
}()

但得到:无法将类型“(NSObject)->()-> WhereViewController”的值分配给类型“WhereViewController?”

有人可以帮我吗?还是不能与 collectionView (containerView) 中的 navigationController “对话”?

我不使用故事板

【问题讨论】:

    标签: ios swift uinavigationcontroller uicollectionview swift4


    【解决方案1】:

    尝试:

    1) 添加扩展:

    extension UIView {
    
       var parentViewController: UIViewController? {
          var parentResponder: UIResponder? = self
          while parentResponder != nil {
             parentResponder = parentResponder!.next
             if parentResponder is UIViewController {
                return parentResponder as! UIViewController!
             }
          }
    
          return nil
       }
    }
    

    2) 现在你可以使用:

    parentViewController?.present(<ControllerName>, animated: true)
    

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      您应该使视图控制器符合集合委托方法,而不是集合视图本身

      使WhereViewController符合UICollectionViewDataSourceUICollectionViewDelegateUICollectionViewDelegateFlowLayout

      class WhereViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
      

      WhereViewControllerviewDidLoad方法中,设置委托和数据源:

      override func viewDidLoad() {
          super.viewDidLoad()
      
          typeCollectionView.dataSource = self
          typeCollectionView.delegate = self
      
          [...]
      }
      

      【讨论】:

      • 我已经实现了代码,在:“(typeCollectionView.collectionViewLayout as?UICollectionViewFlowLayout)?.delegate = self”我有一个错误:“'UICollectionViewFlowLayout'类型的值没有成员'委托”。
      【解决方案3】:

      在这里您可以使用委托将消息从CollectionView 发送到 ViewController.

      简单地声明一个协议

      protocol CustomDelegate: class {
          func collectionView(DidSelect : Int)
      }
      

      然后在WhereCollectionView类中创建一个CustomDelegate协议的实例

      class WhereCollectionView: UICollectionView {
      
      weak var customDelegate:CustomDelegate?
      
      }
      

      didSelect 方法中触发委托方法

      func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
         if let _del = customDelegate {
               _del.collectionView(DidSelect : IndexPath.row)
      }
      
      }
      

      ViewController 中,您将在viewcontroller 中添加collectionviewdelegate 设置为self

      override func viewDidLoad() {
          super.viewDidLoad()
      
          navigationItem.title = "Schaden melden"
      
          view.backgroundColor = UIColor.white
      
         typeCollectionView.customDelegate = self
      
          view.addSubview(progressContainerView)
          view.addSubview(questionLabel)
          view.addSubview(typeCollectionView)
      
          setupProgressContainerView()
          setupQuestionLabel()
          setupTypeCollectionView()
      }
      

      同样在ViewController中实现Custom委托方法

      func collectionView(DidSelect : Int) {
         /// from there you can do your job
      }
      

      【讨论】:

      • 我尝试遵循您的代码。此时:weak var delegate:CustomDelegate?我收到一个错误,说:“属性 'delegate' 类型为 'CustomDelegate?'无法覆盖类型为 'UICollectionViewDelegate?' 的属性";你能帮忙吗?
      • 你得到这个错误 UICollectionView 已经有委托变量。只需更改 CustomDelegate 变量的名称,您的问题就会得到解决。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-22
      相关资源
      最近更新 更多