【发布时间】:2014-08-13 02:07:18
【问题描述】:
有没有办法改变 SLComposeServiceViewController 上的按钮标题?我尝试更改导航项上的条形按钮项,但这些不是正确的按钮。
【问题讨论】:
标签: ios button uiviewcontroller ios8 ios-app-extension
有没有办法改变 SLComposeServiceViewController 上的按钮标题?我尝试更改导航项上的条形按钮项,但这些不是正确的按钮。
【问题讨论】:
标签: ios button uiviewcontroller ios8 ios-app-extension
只需从 navigationController!.navigationBar 访问即可。以下应该会有所帮助。
self.navigationController!.navigationBar.topItem!.rightBarButtonItem!.title = "Save"
【讨论】:
我刚刚找到了一种方法:
class CustomServiceViewController: SLComposeServiceViewController {
override func viewDidLoad() {
let navigationBar = view.subviews.first?.subviews?.last? as? UINavigationBar
let postButton = navigationBar?.subviews.last? as? UIButton
let cancelButton = navigationBar?.subviews.last? as? UIButton
postButton?.setTitle("Done", forState: .Normal)
}
}
请注意 - 这是一个脆弱的解决方案,基于 SLComposeServiceViewController 的未记录内部结构
【讨论】:
super.viewDidLoad()。
Kasztan 的答案不再适用于最新的 iOS;这是最新的脆弱解决方案..
class CustomServiceViewController: SLComposeServiceViewController {
override func viewDidLoad() {
let navigationBar = view.subviews.last?.subviews?.last? as? UINavigationBar
let postButton = navigationBar?.subviews[3] as? UIButton
postButton?.setTitle("Done", forState: .Normal)
}
}
【讨论】:
编辑 #3:适用于 iOS 9 和 iOS 10 beta 的解决方案
之前的方法在 iOS 9 上停止工作,但以下方法似乎再次有效(在 iOS 9 和 10 beta 2 上测试):
1) 首先,您需要添加一个 UIFont 类扩展来检查按钮字体是否为粗体(这是因为 Post 按钮始终为粗体); here's how.
2) 然后,在viewDidAppear: 中,我们需要以下代码(我在编辑 2 中编写的代码的更新版本):
if let navigationBar = self.navigationController?.navigationBar {
// First, let's set backgroundColor and tintColor for our share extension bar buttons
navigationBar.backgroundColor = UIColor.darkGrayColor()
navigationBar.tintColor = UIColor.whiteColor()
if let navBarSubviews = navigationBar.subviews as? [UIView] {
for eachView in navBarSubviews {
if let navBarButton = eachView as? UIButton {
// Second, let's set our custom titles for both buttons (Cancel and Post); checking for the title wouldn't work for localized devices, so we check if the button is bold (Post) or not (Cancel) via the UIFont class extension above.
let buttonFont : UIFont? = navBarButton.titleLabel?.font
if buttonFont?.isBold == true {
navBarButton.setTitle("Save", forState: .Normal)
} else {
navBarButton.setTitle("Cancel", forState: .Normal)
}
}
}
}
}
当然,这现在有效,但它可能会在未来再次崩溃......
编辑 #2:我让它在装有 iOS 8.4 的设备上运行 :)
事实证明我错了,在这方面花费了不合理的时间后我已经能够同时更改按钮及其文本的颜色。
这是我的代码,需要放在ViedDidAppear()中(如果你把它放在viewDidLoad()里面就不行了!):
if let navigationBar = self.navigationController?.navigationBar {
// First, let's set backgroundColor and tintColor for our share extension bar buttons
navigationBar.backgroundColor = UIColor.darkGrayColor()
navigationBar.tintColor = UIColor.whiteColor()
if let navBarSubviews = navigationBar.subviews as? [UIView] {
for eachView in navBarSubviews {
if let navBarButton = eachView as? UIButton {
// Second, let's set our custom titles for both buttons (Cancel and Post); checking for the title wouldn't work on localized devices, so we check if the current button is emphasized (Post) or not (Cancel) via an UIFontDescriptor.
let fontDescriptor : UIFontDescriptor? = navBarButton.titleLabel?.font.fontDescriptor()
if let descriptor = fontDescriptor {
let fontAttributes : NSDictionary = descriptor.fontAttributes()
var buttonFontIsEmphasized : Bool? = fontAttributes["NSCTFontUIUsageAttribute"]?.isEqualToString("CTFontEmphasizedUsage")
if buttonFontIsEmphasized == true {
navBarButton.setTitle("Save", forState: .Normal)
} else {
navBarButton.setTitle("Cancel", forState: .Normal)
}
}
}
}
}
}
不过,我不确定这是否应该在发货应用程序上完成,也不能通过应用程序审查(不过应该,因为它不会与私有 API 混淆)。 此外,应该注意 这可能随时中断,即使它不应该像以前的解决方案那样容易被破坏(它遍历子视图并尝试向下转换它们,所以在视图层次结构不应使其无用);我的期望是,即使将来它停止工作,它也不应该使共享扩展崩溃。
原答案
我相信你(和我)想要做的事情已经不可能了,可能是有意为之。原因如下:
受@Kasztan 和@Paito 回答的启发,我在ShareViewController 的viewDidLoad() 中尝试了这个:
for eachView in view.subviews {
println("1")
for eachSubView in eachView.subviews {
println("2")
if let navigationBarView = eachSubView as? UINavigationBar {
println("3")
for eachNavBarSubView in navigationBarView.subviews {
println("4")
if let navBarButton = eachNavBarSubView as? UIButton {
println("5")
println(navBarButton.titleForState(.Normal))
navBarButton.setTitleColor(UIColor.redColor(), forState: .Normal)
navBarButton.setTitle("My text", forState: .Normal)
navBarButton.tintColor = UIColor.redColor()
navBarButton.setNeedsLayout()
navBarButton.layoutIfNeeded()
}
}
}
}
}
并不是说我认为这样的东西应该在应用程序中发布,但作为概念证明,这应该是可行的,而且从理论上讲,在未来的操作系统版本中应该不会那么容易破解.
除了,它在 iOS 8.4 上对我不起作用:我看到记录的所有检查点消息,从 1 到 5,其中一些是多次(因为它应该是,因为代码尝试所有可能的子视图)。
“5”消息被记录了两次,这是有道理的,因为这意味着它成功地向下转换了两个按钮,取消和发布,但没有改变默认的文本和颜色。
我的结论是,Apple 代码中的某些内容阻止我们更改这些按钮的外观。
当然,如果有人找到解决方案,我很乐意对我自己的答案投反对票(如果可以的话,我很确定);)
EDIT #1:最后一次检查,我也记录了按钮标题,在按钮向下转换 (5) 之后,是的,我得到了 Optional("Cancel") 和 Optional("Post" ) 在控制台中,因此此解决方案获得了正确的按钮,但无法对其进行编辑。
【讨论】: