Swift 在Xcode中导航栏控制器的标题下添加字幕
所以我想在导航控制器的导航栏标题下添加一个“字幕” 到目前为止,我查找的所有内容都希望我使用CGRect。我不知道那是什么,听起来好像是想让我创造一个全新的视角,这不是我想要做的 我的问题是,是否有一个点的方法来添加字幕视图容易 我找到的最接近的东西是在stack overflow上发布的,下面是链接: 显然,去年这是有效的,但现在我得到了错误,它在我的viewDidLoad 我试过这个: self.navigationController?.navigationItem.prompt=“此处字幕” 这是唯一不会显示任何错误但仍然不起作用的东西。它实际上什么也不做。运行时至少没有可见的内容Swift 在Xcode中导航栏控制器的标题下添加字幕,swift,uinavigationcontroller,uinavigationbar,uinavigationitem,Swift,Uinavigationcontroller,Uinavigationbar,Uinavigationitem,所以我想在导航控制器的导航栏标题下添加一个“字幕” 到目前为止,我查找的所有内容都希望我使用CGRect。我不知道那是什么,听起来好像是想让我创造一个全新的视角,这不是我想要做的 我的问题是,是否有一个点的方法来添加字幕视图容易 我找到的最接近的东西是在stack overflow上发布的,下面是链接: 显然,去年这是有效的,但现在我得到了错误,它在我的viewDidLoad 我试过这个: self.navigationController?.navigationItem.prompt=“此处
另一方面,斯威夫特是首选。谢谢 虽然有一个解决方案,但它有一些已知的问题 解决方案是编写这样的函数
func setTitle(title:String, subtitle:String) -> UIView {
let titleLabel = UILabel(frame: CGRectMake(0, -2, 0, 0))
titleLabel.backgroundColor = UIColor.clearColor()
titleLabel.textColor = UIColor.grayColor()
titleLabel.font = UIFont.boldSystemFontOfSize(17)
titleLabel.text = title
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRectMake(0, 18, 0, 0))
subtitleLabel.backgroundColor = UIColor.clearColor()
subtitleLabel.textColor = UIColor.blackColor()
subtitleLabel.font = UIFont.systemFontOfSize(12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
let titleView = UIView(frame: CGRectMake(0, 0, max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), 30))
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width
if widthDiff < 0 {
let newX = widthDiff / 2
subtitleLabel.frame.origin.x = abs(newX)
} else {
let newX = widthDiff / 2
titleLabel.frame.origin.x = newX
}
return titleView
}
唯一已知的问题是,如果字幕变得非常大,就会发生错位
最终结果
来源:非常感谢您的回答@拉詹马赫什瓦里 除了使用widthDiff 我调整了一下,一切都很顺利
if widthDiff < 0 {
let newX = widthDiff / 2
subtitleLabel.frame.origin.x = abs(newX)
} else {
let newX = widthDiff / 2
titleLabel.frame.origin.x = newX
}
如果widthDiff<0{
设newX=widthDiff/2
subtitleLabel.frame.origin.x=abs(newX)
}否则{
设newX=widthDiff/2
titleLabel.frame.origin.x=newX
}
再次感谢您的回复 这是我在扩展上使用堆栈视图的版本
extension UINavigationItem {
func setTitle(title:String, subtitle:String) {
let one = UILabel()
one.text = title
one.font = UIFont.systemFont(ofSize: 17)
one.sizeToFit()
let two = UILabel()
two.text = subtitle
two.font = UIFont.systemFont(ofSize: 12)
two.textAlignment = .center
two.sizeToFit()
let stackView = UIStackView(arrangedSubviews: [one, two])
stackView.distribution = .equalCentering
stackView.axis = .vertical
stackView.alignment = .center
let width = max(one.frame.size.width, two.frame.size.width)
stackView.frame = CGRect(x: 0, y: 0, width: width, height: 35)
one.sizeToFit()
two.sizeToFit()
self.titleView = stackView
}
}
谢谢你的回答@RajanMaheshwari 如果有人在字幕文本比标题文本长时出现标题不对齐的问题,我将以下代码添加到Rajan的答案中,该答案位于字幕标签实例化的正下方:
// Fix incorrect width bug
if (subtitleLabel.frame.size.width > titleLabel.frame.size.width) {
var titleFrame = titleLabel.frame
titleFrame.size.width = subtitleLabel.frame.size.width
titleLabel.frame = titleFrame
titleLabel.textAlignment = .center
}
希望这能帮助那些遇到与我相同问题的人另一种解决方案,只使用一个标签和
nsattributestring
来区分标题和副标题(不同的字体大小、权重、颜色等)。消除了不同标签对齐的问题
extension UIViewController {
func setTitle(_ title: String, subtitle: String) {
let rect = CGRect(x: 0, y: 0, width: 400, height: 50)
let titleSize: CGFloat = 20 // adjust as needed
let subtitleSize: CGFloat = 15
let label = UILabel(frame: rect)
label.backgroundColor = .clear
label.numberOfLines = 2
label.textAlignment = .center
label.textColor = .black
let text = NSMutableAttributedString()
text.append(NSAttributedString(string: title, attributes: [.font : UIFont.boldSystemFont(ofSize: titleSize)]))
text.append(NSAttributedString(string: "\n\(subtitle)", attributes: [.font : UIFont.systemFont(ofSize: subtitleSize)]))
label.attributedText = text
self.navigationItem.titleView = label
}
}
自定义标题视图部分基于,以防任何人寻找上述解决方案的
Objective-C
代码:
UILabel *title = [[UILabel alloc]init];
UILabel *subtitle = [[UILabel alloc]init];
[title setFont:[UIFont systemFontOfSize:12]];
[title setTextColor:[UIColor whiteColor]];
[title setFont:[UIFont systemFontOfSize:17]];
[title sizeToFit];
title.text = @"Title";
[subtitle setTextColor:[UIColor whiteColor]];
[subtitle setFont:[UIFont systemFontOfSize:12]];
[subtitle setTextAlignment:NSTextAlignmentCenter];
[subtitle sizeToFit];
subtitle.text = @"Subtitle Title";
UIStackView *stackVw = [[UIStackView alloc]initWithArrangedSubviews:@[title,subtitle]];
stackVw.distribution = UIStackViewDistributionEqualCentering;
stackVw.axis = UILayoutConstraintAxisVertical;
stackVw.alignment =UIStackViewAlignmentCenter;
[stackVw setFrame:CGRectMake(0, 0, MAX(title.frame.size.width, subtitle.frame.size.width), 35)];
self.navigationItem.titleView = stackVw;
我真的很喜欢@user2325031的答案,但我发现不需要调整标签的大小以适应并设置框架。根据@GerardoMR的建议,我还将stackView的对齐设置为.center
extension UINavigationItem {
func setTitle(_ title: String, subtitle: String) {
let titleLabel = UILabel()
titleLabel.text = title
titleLabel.font = .systemFont(ofSize: 17.0)
titleLabel.textColor = .black
let subtitleLabel = UILabel()
subtitleLabel.text = subtitle
subtitleLabel.font = .systemFont(ofSize: 12.0)
subtitleLabel.textColor = .gray
let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
stackView.distribution = .equalCentering
stackView.alignment = .center
stackView.axis = .vertical
self.titleView = stackView
}
}
Swift 4:
import UIKit
class NavigationTitleView: UIView {
private var contentStackView = UIStackView()
private var titleLabel = UILabel()
private var subTitleLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
viewConfig()
addViewsConfig()
layoutViewsConfig()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func set(title: String, subTitle: String){
self.titleLabel.text = title
self.subTitleLabel.text = subTitle
}
private func viewConfig() {
contentStackView.axis = .vertical
contentStackView.alignment = .center
contentStackView.distribution = .fill
contentStackView.spacing = 5
self.backgroundColor = .clear
self.titleLabel.textColor = .white
self.self.subTitleLabel.textColor = .white
}
private func addViewsConfig() {
contentStackView.addArrangedSubview(subTitleLabel)
contentStackView.addArrangedSubview(titleLabel)
self.addSubview(contentStackView)
}
private func layoutViewsConfig(){
contentStackView.translatesAutoresizingMaskIntoConstraints = false
contentStackView.centerXAnchor.constraint(equalTo: self.centerXAnchor, constant: 0.0).isActive = true
contentStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0.0).isActive = true
}
}
使用:
@iosjillian的Swift 4扩展功能非常出色,增加了更多功能,以尊重酒吧的外观和用户字体偏好:
import UIKit
extension UINavigationItem {
func setTitle(_ title: String, subtitle: String) {
let appearance = UINavigationBar.appearance()
let textColor = appearance.titleTextAttributes?[NSAttributedString.Key.foregroundColor] as? UIColor ?? .black
let titleLabel = UILabel()
titleLabel.text = title
titleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.headline)
titleLabel.textColor = textColor
let subtitleLabel = UILabel()
subtitleLabel.text = subtitle
subtitleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.subheadline)
subtitleLabel.textColor = textColor.withAlphaComponent(0.75)
let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
stackView.distribution = .equalCentering
stackView.alignment = .center
stackView.axis = .vertical
self.titleView = stackView
}
}
您是否尝试过将字幕置于标题上方而非下方的
self.navigationItem.prompt=“Subtitle”
?@tktsubotatitle@RajanMaheshwari是的,我做了一个测试,发现了。@tktsubota你在开玩笑吗?它不是字幕,而是导航栏上方的一个新的独立栏,有自己的标题,这样你就有了两个栏,没用了!它将帮助您所有现有的场景,它的代码比我预期的要多得多,但它确实有效。我真的希望苹果能增加一个更简单的方法。字幕看起来并不像是那么牵强。。(顺便说一句,非常感谢!)@拉贾尼需要这样的东西,若标题是空的,那个么标题应该在中间。我必须在聊天应用程序中实现。如果用户开始键入,则显示字幕。欲了解更多信息,请参阅whatsApp.title和subtitle从导航控制器按下时从左向左滑动到中间任何解决方案@naveeds以上解决方案都可以使两个文本居中,在我的情况下,它的工作非常好!标题和副标题从左边滑到中间当从导航控制器按任何解决方法到我,这是更干净的答案,它没有魔术数字作为第一个答案。我只会在设置轴后添加stackView.alignment=.center
,否则如果字幕更大,它不会完全居中显示。另外,我将删除对sizeToFit()
的最后两个调用,因为您在标签上调用了它们。默认标题是否也具有恒定的字体值17?这非常有效。根据上面的@GerardoMR注释,您可以使用UIStackView设置将标题/副标题居中:stackView.alignment=.center
import UIKit
class ViewController: UIViewController {
private var navigationTitleView = NavigationTitleView()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.titleView = navigationTitleView
navigationTitleView.set(title: "title", subTitle: "subTitle")
}
}
import UIKit
extension UINavigationItem {
func setTitle(_ title: String, subtitle: String) {
let appearance = UINavigationBar.appearance()
let textColor = appearance.titleTextAttributes?[NSAttributedString.Key.foregroundColor] as? UIColor ?? .black
let titleLabel = UILabel()
titleLabel.text = title
titleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.headline)
titleLabel.textColor = textColor
let subtitleLabel = UILabel()
subtitleLabel.text = subtitle
subtitleLabel.font = .preferredFont(forTextStyle: UIFont.TextStyle.subheadline)
subtitleLabel.textColor = textColor.withAlphaComponent(0.75)
let stackView = UIStackView(arrangedSubviews: [titleLabel, subtitleLabel])
stackView.distribution = .equalCentering
stackView.alignment = .center
stackView.axis = .vertical
self.titleView = stackView
}
}