【问题标题】:UICollectionView iOS 9 issue on project with RTL languages support支持 RTL 语言的项目上的 UICollectionView iOS 9 问题
【发布时间】:2016-01-12 20:04:56
【问题描述】:

似乎Apple在RTL语言上的自动翻转界面新功能在使用UICollectionView时会导致问题。

我在集合视图中使用了 Trailing/Leading 类型的约束,它们在 RTL 语言上切换了它们的值。

问题是实际呈现的数据是集合数据源中最后一个 indexPath,但第一个单元格的UIScrollView.contentOffset.x 是0。

正确的行为应该是以下之一:

  1. 正确显示第一个 indexPath 并切换滚动方向(向右) - 最佳选择
  2. 不翻转 UI/约束,因此呈现的数据/indexPath/scrollView.contentOffset.x 将同步 - 禁用 RTL 支持的选项。
  3. 显示最后一个 indexPath 的单元格和数据,但同时修复 scrollView.contentOffset.x 以表示最后一个单元格位置。

我猜 Apple 可能会在未来某个时候修复它,但同时我们将不得不使用诸如反转数组和/或滚动到最后一个对象之类的变通方法。

【问题讨论】:

  • 能否请您在bugreport.apple.com 提交错误报告?
  • @wakachamo 会的!感谢您的直接链接...
  • 如果您确实实施了解决方法,请滚动视图而不是反转数组 - 错误位于初始位置,而不是布局本身。
  • 您收到 Apple 的回复了吗?也可能值得将此添加到 openradar.appspot.com 以帮助其他人跟踪问题。
  • 我有另一个关于 UICollectionViewFlowLayout 和 RTL 的问题。如果我为单元格返回不同大小,则布局始终是 LTR。 :O

标签: ios autolayout uicollectionview ios9 right-to-left


【解决方案1】:

我迟到了,但如果你不想创建扩展,因为它会影响我们应用中的所有集合视图。只需创建您自己的自定义类,即。

class customLayoutForLocalization : UICollectionViewFlowLayout{
    open override var flipsHorizontallyInOppositeLayoutDirection: Bool {
         return true
    } 
}

要使用这个类:

// your way of deciding on whether you need to apply this layout may vary depending on use of other tools like LanguageManager_iOS to handle multi-language support
if myCollectionView.effectiveUserInterfaceLayoutDirection == .rightToLeft  {
    let customLayout = customLayoutForRTL()
    // if your elements are variable size use the following line
    customLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
    // if you want horizontal scroll (single line)
    customLayout.scrollDirection = .horizontal
    myCollectionView.collectionViewLayout = customLayout
}

【讨论】:

  • 我猜这是最好的解决方案。谢谢萌
【解决方案2】:

虽然简单的数学可以解决问题,但并不漂亮。 (水平collectionview)

- (void)switchSemanticDirection:(UISwitch*)sender {
    //TEST switch the semantic direction between LTR and RTL.
    if (sender.isOn) {
        UIView.appearance.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
    } else {
        UIView.appearance.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
    }

    [self.myContent removeFromSuperview];
    [self.view addSubview:self.myContent];
    
    //reload your collection view to apply RTL setting programmatically
    [self.list reloadData];
    //position your content into the right offset after flipped RTL
    self.list.contentOffset = CGPointMake(self.list.contentSize.width - self.list.contentOffset.x - self.list.bounds.size.width, 
    self.list.contentOffset.y);
}

【讨论】:

    【解决方案3】:
    import UIKit
    
    extension UICollectionViewFlowLayout {
    
        open override var flipsHorizontallyInOppositeLayoutDirection: Bool {
            return UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft
        }
    

    【讨论】:

    • 如果您可以添加注释向其他人解释您的代码,那就太好了
    【解决方案4】:

    该问题有一个对我有用的通用解决方案,请按照以下步骤克服该问题,

    • 根据您的要求提供自动布局约束,然后从属性检查器将集合视图的语义控制属性更改为从故事板强制从右到左。

    • 然后打开故事板作为源代码并找到相关集合视图的“前导”属性并将其替换为“左”,同样的“尾随”将其替换为“右”。现在你差不多完成了。

    • 现在它将根据您的要求为您提供结果。

    【讨论】:

      【解决方案5】:

      我遇到了类似的情况,并找到了解决方案。如果您使用的是 swift,请将以下 sn-p 添加到您的项目中,它将确保 bounds.origin 始终跟随集合视图的前沿。

      extension UICollectionViewFlowLayout {
      
          open override var flipsHorizontallyInOppositeLayoutDirection: Bool {
              return true
          }
      }
      

      如果您使用的是 Objective-C,只需子类化 UICollectionViewLayout 类,并覆盖 flipsHorizo​​ntallyInOppositeLayoutDirection,并返回 true。使用这个子类作为你的集合视图的布局对象。

      【讨论】:

      • 当您对答案投反对票时,请礼貌地添加评论为什么?这样每个人都可以了解为什么这是一种不好的方法。
      • 简单有效的解决方案。
      • 这对于任何带有 UICollectionViewFlowLayout 的 UICollectionView 来说都是必须的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 2015-02-08
      • 2015-10-18
      • 2011-08-05
      • 2012-12-21
      • 1970-01-01
      相关资源
      最近更新 更多