为 UITabBarController 使用自定义 collectionView
Posted
技术标签:
【中文标题】为 UITabBarController 使用自定义 collectionView【英文标题】:Using custom collectionView for the UITabBarController 【发布时间】:2017-02-15 12:06:10 【问题描述】:我有一个自定义的UIView
,称为MenuBar
。这个菜单栏是一个自定义的“标签栏”,里面有一个collectionView
,里面有5个单元格。当一个单元格被点击时,我想显示一个ViewController
,但我不能在我的didSelect
方法中调用类似下面的代码,因为我无法访问当前函数:
if indexPath.item == 1
let dummyController = DummyController()
present(dummyController, animated: true, completion: nil)
有人有解决办法吗?任何帮助将不胜感激。谢谢你们。我的代码如下:
class MenuBar: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
lazy var collectionView: UICollectionView =
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = .clear
cv.delegate = self
cv.dataSource = self
return cv
()
let seperatorView: UIView =
let view = UIView()
view.backgroundColor = lightGray
return view
()
let imageNames = ["home_selected", "glimpse_selected", "camera_selected", "activity_selected", "profile_selected"]
override init(frame: CGRect)
super.init(frame: frame)
addSubview(collectionView)
addSubview(seperatorView)
collectionView.register(MenuCell.self, forCellWithReuseIdentifier: "cellId")
let selectedIndexPath = IndexPath(item: 0, section: 0)
collectionView.selectItem(at: selectedIndexPath, animated: false, scrollPosition: .centeredHorizontally)
_ = collectionView.anchor(self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
_ = seperatorView.anchor(collectionView.topAnchor, left: collectionView.leftAnchor, bottom: nil, right: collectionView.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 1)
setupHorizontalBar()
var horizontalBarLeftAnchorConstraint: NSLayoutConstraint?
func setupHorizontalBar()
let horizontalBarView = UIView()
horizontalBarView.translatesAutoresizingMaskIntoConstraints = false
horizontalBarView.backgroundColor = .darkGray
addSubview(horizontalBarView)
horizontalBarLeftAnchorConstraint = horizontalBarView.leftAnchor.constraint(equalTo: self.leftAnchor)
horizontalBarLeftAnchorConstraint?.isActive = true
horizontalBarView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
horizontalBarView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1/5).isActive = true
horizontalBarView.heightAnchor.constraint(equalToConstant: 4).isActive = true
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
let x = CGFloat(indexPath.item) * frame.width / 5
horizontalBarLeftAnchorConstraint?.constant = x
UIView.animate(withDuration: 0.45, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations:
self.layoutIfNeeded()
, completion: nil)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 5
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! MenuCell
cell.imageView.image = UIImage(named: imageNames[indexPath.item])?.withRenderingMode(.alwaysTemplate)
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: self.frame.width / 5, height: self.frame.height)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat
return 0
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
【问题讨论】:
【参考方案1】:为您的自定义视图定义一个委托,当拥有该视图的视图控制器创建它时,它可以将自己设置为委托并自行处理演示。
例如
protocol MenuBarDelegate: class
func didSelectItem(index: IndexPath, menuBar: MenuBar)
class MenuBar
weak var delegate: MenuBarDelegate?
然后在创建菜单栏的视图控制器中:
menuBar.delegate = self
实现 didSelectItem 方法并在那里处理它 - 您实际上是在制作您自己版本的 Apple 无处不在的委托模式,他们在所有视图上都使用它。您可能希望将所选项目建模为 indexPath 以外的东西,但我不知道您的代码。
我建议您始终将模型逻辑与视图逻辑分离。例如,视图永远不应该知道它正在显示的模型,并且不应该知道用户与之交互时要做什么。这应该始终解耦并转发。
【讨论】:
能否请您在上面的代码中提供一个示例?我有点新手。很抱歉成为一个痛苦的人。谢谢您的回答!真的很感激。***人物 您只需将协议添加到 MenuBar 文件的顶部,然后将该属性添加到 menuBar。然后,无论您在何处创建 MenuBar 本身并将其添加到视图层次结构中,都将委托设置为该视图控制器并在协议定义中实现所需的功能。 developer.apple.com/library/prerelease/content/documentation/…developer.apple.com/library/content/documentation/General/…Objective-C 但相关【参考方案2】:我同意@Jeff 的观点,即模型逻辑应始终与视图逻辑分离。但是,我最近实现了自己的 Tabbar,并通过以下方式实现了它:
-
我在 AppDelegate 中实例化了一个
UINavigationController
,以便我可以从任何地方访问它。
然后在您的自定义MenuBar
中,您可以通过调用(UIApplication.shared.delegate as AppDelegate).YOURNAVIGATIONCONTROLLER
来访问此导航控制器,并使用它来呈现您想要呈现的视图控制器。
如果您确实想将MenuBar
用作UITabbarController
,则应始终将要显示的视图控制器设置为导航控制器的rootViewController,如下所示:
var appDelegate = UIApplication.shared.delegate as?应用委托 appDelegate?.YOURNAVIGATIONCONTROLLER?.viewControllers = [(DummyController())!]
希望有用!
【讨论】:
以上是关于为 UITabBarController 使用自定义 collectionView的主要内容,如果未能解决你的问题,请参考以下文章
iOS边练边学--UITabBarController的简单使用
一起使用 UITabBarController 和 UINavigationController