iOS - 今天分机 'show more' & 'show less' 状态不正确。折叠显示 'show less' - 需要多次按下才能修复
iOS - Today Extension 'show more' & 'show less' state incorrect. Collapsed says 'show less' - requiring multipule presses to fix
我有一个扩展程序,我拆掉了基本结构,它使自己处于不正确的状态,当它折叠时会显示 "Show Less"。
这发生在两种情况下
- 我用 "Show More" 展开扩展,然后离开
屏幕。我打开另一个应用程序,然后 return 到扩展程序。
扩展的扩展在我面前明显崩溃了,但仍然
说 "Show Less"
- 我推送一个新版本来测试更改。它将比以前扩展,
当新构建推送时,它会折叠并显示 "show less"
我还尝试过在扩展时激活另一个扩展(天气),并且在扩展后始终保持扩展状态,而我的扩展正在折叠并显示错误状态。
无论是否存在天气小部件,都会发生这种情况。
当我在代码中放置断点时,在步骤 #1 中再次调用 ViewDidLoad。
这是代码,我一点一点地删除了所有内容,直到剩下所有内容,但仍然导致问题。
class TodayController: UICollectionViewController, NCWidgetProviding {
let reuseIdentifier = "TimeGridCell"
override func viewDidLoad() {
super.viewDidLoad()
self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return 3
}
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
for: indexPath) as! ArtistTimeGridTableViewCell
cell.nameLabel.text = "blah blah"
return cell
}
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
if activeDisplayMode == .expanded {
self.preferredContentSize = (self.collectionView?.contentSize)!
} else if activeDisplayMode == .compact {
self.preferredContentSize = maxSize
}
}
}
请注意,如果我删除 self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
,那么我根本无法获得展开或折叠的选项,因此这是必需的。
这是问题的图片。第一张正确,第二张错误。
发现另一个人在谈论按钮无法正常工作的问题,他们的解决方案似乎对我有用,尽管没有很好的解释到底出了什么问题?这似乎是一个 OS 错误?
iOS10 widget "Show more" "Show less" bug
延迟设置内容大小可防止出现此问题
let deadlineTime = DispatchTime.now() + 0.2
if activeDisplayMode == .expanded {
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
self.preferredContentSize = (self.collectionView?.contentSize)!
}
} else if activeDisplayMode == .compact {
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
self.preferredContentSize = maxSize
}
}
我遇到了完全相同的问题,但我使用布局约束来设置展开状态的高度。对于遇到此问题的任何人,修复只是将 layoutIfNeeded 添加到 widgetActiveDisplayModeDidChange 的末尾。
用法示例:
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
switch activeDisplayMode {
case .compact:
heightContstraint.constant = 0
case .expanded:
heightContstraint.constant = 44 * CGFloat((items.count))
}
view.layoutIfNeeded()
}
刚找到正确答案。
由于您允许扩展在 viewDidLoad 中扩展大小,因此直接从 viewDidLoad 调用 widgetActiveDisplayModeDidChange 。
问题在于在您的 widgetActiveDisplayModeDidChange 方法中访问 collection/table 视图属性(size/element 号),因为 collection/table 视图完全仅在 viewWillAppear.
后初始化
因此,就我而言,我只是在 widgetActiveDisplayModeDidChange 中复制了 numberOfRowsInSection 计算,然后一切都开始按预期工作。
在Swift3和4
override func viewDidLoad() {
super.viewDidLoad()
self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
}
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
if activeDisplayMode == .expanded {
self.preferredContentSize = (self.myTableView?.contentSize)!
//Instead of table content you can user user own size
} else if activeDisplayMode == .compact {
self.preferredContentSize = maxSize
}
}
真正的问题是在 widgetActiveDisplayModeDidChange 期间,collectionView 还不知道 contentSize,所以它会给你一个较小的值。如果你在函数中打印出来,和viewWillAppear对比一下,你就会发现区别了。
0.2 秒的延迟似乎很老套,所以我更喜欢这样:
override func viewWillAppear(_ animated: Bool) {
if (extensionContext?.widgetActiveDisplayMode == .expanded) {
self.preferredContentSize = self.collectionView.contentSize
}
}
它同样适用于 tableView,这是我正在使用的小部件。如果您滑动到主屏幕并向后滑动,上面的代码将处理这种情况。但是如果你只是点击显示它不会被触发more/less,所以你仍然需要在widgetActiveDisplayModeDidChange中维护相同的代码。
我有一个扩展程序,我拆掉了基本结构,它使自己处于不正确的状态,当它折叠时会显示 "Show Less"。
这发生在两种情况下
- 我用 "Show More" 展开扩展,然后离开 屏幕。我打开另一个应用程序,然后 return 到扩展程序。 扩展的扩展在我面前明显崩溃了,但仍然 说 "Show Less"
- 我推送一个新版本来测试更改。它将比以前扩展, 当新构建推送时,它会折叠并显示 "show less"
我还尝试过在扩展时激活另一个扩展(天气),并且在扩展后始终保持扩展状态,而我的扩展正在折叠并显示错误状态。
无论是否存在天气小部件,都会发生这种情况。
当我在代码中放置断点时,在步骤 #1 中再次调用 ViewDidLoad。
这是代码,我一点一点地删除了所有内容,直到剩下所有内容,但仍然导致问题。
class TodayController: UICollectionViewController, NCWidgetProviding {
let reuseIdentifier = "TimeGridCell"
override func viewDidLoad() {
super.viewDidLoad()
self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return 3
}
override func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
for: indexPath) as! ArtistTimeGridTableViewCell
cell.nameLabel.text = "blah blah"
return cell
}
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
if activeDisplayMode == .expanded {
self.preferredContentSize = (self.collectionView?.contentSize)!
} else if activeDisplayMode == .compact {
self.preferredContentSize = maxSize
}
}
}
请注意,如果我删除 self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
,那么我根本无法获得展开或折叠的选项,因此这是必需的。
这是问题的图片。第一张正确,第二张错误。
发现另一个人在谈论按钮无法正常工作的问题,他们的解决方案似乎对我有用,尽管没有很好的解释到底出了什么问题?这似乎是一个 OS 错误?
iOS10 widget "Show more" "Show less" bug
延迟设置内容大小可防止出现此问题
let deadlineTime = DispatchTime.now() + 0.2
if activeDisplayMode == .expanded {
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
self.preferredContentSize = (self.collectionView?.contentSize)!
}
} else if activeDisplayMode == .compact {
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
self.preferredContentSize = maxSize
}
}
我遇到了完全相同的问题,但我使用布局约束来设置展开状态的高度。对于遇到此问题的任何人,修复只是将 layoutIfNeeded 添加到 widgetActiveDisplayModeDidChange 的末尾。
用法示例:
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
switch activeDisplayMode {
case .compact:
heightContstraint.constant = 0
case .expanded:
heightContstraint.constant = 44 * CGFloat((items.count))
}
view.layoutIfNeeded()
}
刚找到正确答案。
由于您允许扩展在 viewDidLoad 中扩展大小,因此直接从 viewDidLoad 调用 widgetActiveDisplayModeDidChange 。
问题在于在您的 widgetActiveDisplayModeDidChange 方法中访问 collection/table 视图属性(size/element 号),因为 collection/table 视图完全仅在 viewWillAppear.
后初始化因此,就我而言,我只是在 widgetActiveDisplayModeDidChange 中复制了 numberOfRowsInSection 计算,然后一切都开始按预期工作。
在Swift3和4
override func viewDidLoad() {
super.viewDidLoad()
self.extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
}
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
if activeDisplayMode == .expanded {
self.preferredContentSize = (self.myTableView?.contentSize)!
//Instead of table content you can user user own size
} else if activeDisplayMode == .compact {
self.preferredContentSize = maxSize
}
}
真正的问题是在 widgetActiveDisplayModeDidChange 期间,collectionView 还不知道 contentSize,所以它会给你一个较小的值。如果你在函数中打印出来,和viewWillAppear对比一下,你就会发现区别了。
0.2 秒的延迟似乎很老套,所以我更喜欢这样:
override func viewWillAppear(_ animated: Bool) {
if (extensionContext?.widgetActiveDisplayMode == .expanded) {
self.preferredContentSize = self.collectionView.contentSize
}
}
它同样适用于 tableView,这是我正在使用的小部件。如果您滑动到主屏幕并向后滑动,上面的代码将处理这种情况。但是如果你只是点击显示它不会被触发more/less,所以你仍然需要在widgetActiveDisplayModeDidChange中维护相同的代码。