想要从容器视图推送到另一个视图控制器
Posted
技术标签:
【中文标题】想要从容器视图推送到另一个视图控制器【英文标题】: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 “对话”?
我不使用故事板
【问题讨论】:
【参考方案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
符合UICollectionViewDataSource
、UICollectionViewDelegate
和UICollectionViewDelegateFlowLayout
:
class WhereViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
在WhereViewController
的viewDidLoad
方法中,设置委托和数据源:
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
中添加collectionview
将delegate
设置为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 变量的名称,您的问题就会得到解决。以上是关于想要从容器视图推送到另一个视图控制器的主要内容,如果未能解决你的问题,请参考以下文章
ios - 推送到另一个视图控制器时,应用程序 UI 会阻塞一段时间
将另一个视图控制器推送到 UITabBarController 视图中
如何将新的 viewController 推送到另一个视图控制器中的现有视图中?