Swift 使用UITabBarController的自定义collectionView
我有一个自定义的Swift 使用UITabBarController的自定义collectionView,swift,uiview,swift3,uicollectionview,uicollectionviewcell,Swift,Uiview,Swift3,Uicollectionview,Uicollectionviewcell,我有一个自定义的ui视图,名为MenuBar。此菜单栏是一个自定义“选项卡栏”,其内部有一个包含5个单元格的collectionView。点击单元格时,我想显示一个ViewController,但我无法在我的didSelect方法中调用类似下面的代码,因为我无法访问当前函数: if indexPath.item == 1 { let dummyController = DummyController() present(dummyController, animated: tru
ui视图
,名为MenuBar
。此菜单栏是一个自定义“选项卡栏”,其内部有一个包含5个单元格的collectionView
。点击单元格时,我想显示一个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")
}
}
为自定义视图定义委托,当拥有此视图的视图控制器创建委托时,它可以将自己设置为委托并处理演示文稿本身 例如 然后在创建菜单栏的视图控制器中执行以下操作:
menuBar.delegate = self
实现didSelectItem方法并在那里进行处理——实际上,您正在制作自己版本的Apple无处不在的委托模式,供他们在所有视图中使用。您可能希望将所选项目建模为indexPath以外的内容,但我不知道您的代码
我建议您总是将模型逻辑与视图逻辑解耦。例如,视图永远不应该知道它正在显示的模型,也不应该知道当用户与它交互时该做什么。这应该总是去耦合并转发。我同意@Jeff的观点,模型逻辑应该总是从视图逻辑去耦合。但是,我最近实现了我自己的Tabbar,我是通过以下方式实现的:
UINavigationController
,这样我就可以从任何地方访问它菜单栏
中,您可以通过调用(UIApplication.shared.delegate as AppDelegate)访问此navigationcontroller。您的navigationcontroller
,并使用它显示要显示的viewcontroller菜单栏
用作UITabbarController
,则应始终将要显示为navigationcontroller的rootViewController的viewcontroller设置为如下所示:
var appDelegate=UIApplication.shared.delegate作为?AppDelegate
appDelegate?.YOURNAVIGATIONCONTROLLER?.ViewController=[(DummyController())!]希望这是有用的 你能在上面的代码中提供一个例子吗?我是个新手。对不起,我很痛苦。谢谢你的回答!非常感谢。Top Man您只需将协议添加到菜单栏文件的顶部,然后将该属性添加到菜单栏。然后,无论您在何处创建菜单栏并将其添加到视图层次结构,都要将委托设置为该视图控制器,并在协议定义中实现所需的功能。目标C但相关
menuBar.delegate = self