如何像在 iMessage 群聊中一样在导航栏中放置集合视图
Posted
技术标签:
【中文标题】如何像在 iMessage 群聊中一样在导航栏中放置集合视图【英文标题】:How to put a collection view in the navigation bar like in iMessage group chats 【发布时间】:2016-12-04 21:52:00 【问题描述】:我正在尝试在导航栏中放置一个集合视图,如 iMessage 群聊中所见,其中所有成员的姓名首字母都在导航栏中的圆圈中。
我在 SO 上找到了答案 here,我尽力将其转换为 ios10/Swift 3,但集合视图单元格未正确显示在导航栏中。这是我的代码:
import UIKit
weak var collectionView: UICollectionView?
class ChatController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource
override func viewDidLoad()
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
let collectionView = UICollectionView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(300), height: CGFloat(80)), collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.clear
navigationItem.titleView? = collectionView
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
collectionView.delegate? = self
collectionView.dataSource? = self
view.addSubview(collectionView)
collectionView.reloadData()
func numberOfSections(in collectionView: UICollectionView) -> Int
return 1
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 5
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) )
cell.backgroundColor = UIColor.orange
cell.layer.cornerRadius = 24
return cell
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
return CGSize(width: CGFloat(50), height: CGFloat(50))
还有导航栏类:
import Foundation
import UIKit
class NavigationBar: UINavigationBar
var chatController: ChatController?
override func sizeThatFits(_ size: CGSize) -> CGSize
return CGSize(width: CGFloat(self.superview!.bounds.size.width), height: CGFloat(80))
func setFrame(frame: CGRect)
var f = frame
f.size.height = 80
super.frame = f
看起来集合视图单元格正在显示,但它们位于导航栏下方而不是导航栏内部(见下图)。如果我隐藏导航栏,单元格会转到视图的顶部,但我希望将它们放在导航栏中。
这是我在应用程序委托中的 UI 代码,不确定我是否在这里犯了新手错误:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible()
window?.rootViewController = UINavigationController(rootViewController: ChatController())
return true
我正在以编程方式执行此操作(没有情节提要)。谁能看出我哪里出错了?
【问题讨论】:
调用view.addSubview(collectionView) collectionView.reloadData()
作为viewDidLoad
的最后一次调用。在添加导航栏的位置发布代码。
谢谢,我忘了添加子视图。不幸的是,这并不能解决问题!仍然只是一个普通的视图控制器/导航栏。
展示如何添加 ChatController。
将集合视图添加到导航栏中的标题视图
原谅我,因为我很新,这是我第一次以编程方式做一个界面,但我不是用这行 navigationItem.titleView = collectionView
【参考方案1】:
这是我提出的解决方案
来自Apple
如果您想在导航栏中显示自定义视图,则必须先将这些视图包装在 UIBarButtonItem 对象中,然后再将它们添加到导航项。
有关导航项如何与导航控制器、自定义视图控制器和导航栏协同工作以显示其内容的信息,请参阅View Controller Programming Guide for iOS。
weak var collectionView: UICollectionView?
override func viewDidLoad()
super.viewDidLoad()
let navigationitem = UINavigationItem(title: "") //creates a new item with no title
navigationitem.titleView = collectionView //your collectionview here to display as a view instead of the title that is usually there
self.navigationController?.navigationBar.items = [navigationitem] //adds the navigation item to the navigationbar
从文档中我相信这应该可行。请记住让您的集合视图单元格足够小以适合导航栏。如果它不起作用,请告诉我,也许我明天可以解决一些问题。
【讨论】:
这真的很有趣,我没有意识到你必须将视图包装在一个条形按钮项目中,我会做更多的阅读......虽然很有趣,因为我在我的 OP 中引用的示例( obj-c 中关于 SO 的另一个答案没有这样做就可以正常工作。我尝试了您的代码,但不幸的是发生了崩溃,这是错误:*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法调用 setItems:动画:直接在控制器管理的 UINavigationBar 上。” 谷歌该错误,您会立即找到解决方案。 你能分享一下哪个结果对你有用吗?我搜索了错误并在结果的第一页尝试了解决方案,但问题仍然存在。以上是关于如何像在 iMessage 群聊中一样在导航栏中放置集合视图的主要内容,如果未能解决你的问题,请参考以下文章
如何像在 iOS 中为 iMessage 一样为 Android 创建贴纸包?
TextField 没有被键盘顺利推上,就像在 Whatsapp 和环聊中一样