0

У меня есть пользовательский UIView по имени MenuBar. Эта панель меню представляет собой обычную «панель вкладок», в которой есть collectionView, в которой находится 5 ячеек. Когда клетка прослушиваются, я хочу представить ViewController, но я не могу ничего подобного кода ниже позвонить в мой didSelect метод, потому что я не могу получить доступ к нынешней функции:Использование custom collectionView для UITabBarController

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") 
    } 
} 

ответ

0

Определение делегата для настраиваемого представления и когда контроллер представления, которому принадлежит этот вид создает, он может выступать в качестве делегата и обрабатывать саму презентацию.

E.g.

protocol MenuBarDelegate: class { 
    func didSelectItem(index: IndexPath, menuBar: MenuBar) 
} 

class MenuBar { 
    weak var delegate: MenuBarDelegate? 
} 

Затем в контроллере представления, который создает строку меню сделать:

menuBar.delegate = self 

Реализуйте метод didSelectItem и обработать его там - вы, по сути делаете свою собственную версию вездесущего шаблона делегата от Apple, что они используют на всех своих взглядах. Вы можете захотеть смоделировать выбранный элемент как нечто иное, чем indexPath, но я не знаю вашего кода.

Я рекомендую вам всегда отделять логику модели от логики представления. Например, представление никогда не должно иметь представления о модели, которую оно отображает, и не должно иметь никакого представления о том, что делать, когда пользователь взаимодействует с ним. Это всегда следует отключать и перенаправлять.

+0

Можете ли вы привести пример в коде выше? Я немного новичок. Жаль, что это боль. Спасибо за ваш ответ! Действительно ценю это. Top man – Jimmy

+0

Вам просто нужно добавить протокол в верхнюю часть вашего файла MenuBar, а затем добавить это свойство в menuBar. Затем, где бы вы ни создавали сам MenuBar и не добавляли его в иерархию представлений, установите делегат в этот контроллер представления и выполните требуемую функцию в определении вашего протокола. https://developer.apple.com/library/prerelease/content/documentation/General/Conceptual/DevPedia-CocoaCore/Delegation.html https://developer.apple.com/library/content/documentation/General/Conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html Объектив-C, но релевантный – Tim

0

Я согласен с @Jeff в том, что логика модели всегда должна быть дезактивирована из логики представления. Тем не менее, я недавно внедренная свой собственный TabBar, и я сделал это следующим образом:

  1. Я имел UINavigationController экземпляр в моей AppDelegate, чтобы я мог получить доступ к нему со всех сторон.
  2. Затем в вашем обычном MenuBar вы можете получить доступ к этому навигационному контроллеру, вызвав (UIApplication.shared.delegate as AppDelegate).YOURNAVIGATIONCONTROLLER и использовать его для представления диспетчера представления, который вы хотите представить.
  3. Если вы действительно хотите использовать свой MenuBar как UITabbarController то вы всегда должны установить ViewController вы хотите представить как RootViewController в navigationcontroller следующим образом:

    вар AppDelegate = UIApplication.shared.delegate, как? AppDelegate AppDelegate? .YOURNAVIGATIONCONTROLLER? .viewControllers = [(DummyController())]

Надежда, что было полезно!

 Смежные вопросы

  • Нет связанных вопросов^_^