ios 在 UICollectionView 上从右到左对齐
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25598194/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Aligning right to left on UICollectionView
提问by rebello95
this is a pretty straightforward question, but I haven't been able to find a definitive answer to it on SO (if I missed it, please correct me).
这是一个非常简单的问题,但我无法在 SO 上找到明确的答案(如果我错过了,请纠正我)。
Basically, my question is: Is it possible to align UICollectionView
row contents from right to left instead of from left to right?
基本上,我的问题是:是否可以UICollectionView
从右到左而不是从左到右对齐行内容?
In my research I've seen answers suggesting subclassing UICollectionViewFlowLayout
, but I haven't been able to find an example where one was created for right-alignment.
在我的研究中,我看到了建议 subclassing 的答案UICollectionViewFlowLayout
,但我无法找到一个示例,其中一个是为右对齐创建的。
My goal is to have 2 collection views set up like this:
我的目标是像这样设置 2 个集合视图:
Any help is greatly appreciated!
任何帮助是极大的赞赏!
回答by Tawfik Bouabid
Without doing any Xtransform to the collection view, simply forced RTL:
无需对集合视图进行任何 Xtransform,只需强制 RTL:
YourCollectionView.semanticContentAttribute = UISemanticContentAttribute.forceRightToLeft
回答by LK__
You can get similar result by performing a transform on the collection view and reverse the flip on its content:
您可以通过对集合视图执行转换并反转其内容的翻转来获得类似的结果:
First when creating the UICollectionView I performed a horizontal flip on it:
首先在创建 UICollectionView 时,我对其进行了水平翻转:
[collectionView_ setTransform:CGAffineTransformMakeScale(-1, 1)];
Then subclass UICollectionViewCell
and in here do the same horizontal flip on its contentView:
然后子类化UICollectionViewCell
并在此处对其 contentView 执行相同的水平翻转:
[self.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
回答by medvedNick
In addition to Tawfik's answer:
除了陶菲克的回答:
You can also set UICollectionView's Semantic
property via Interface Builder:
您还可以Semantic
通过 Interface Builder设置 UICollectionView 的属性:
More about this property: in this question
有关此属性的更多信息:在此问题中
回答by Saqib Omer
For anybody trying to achieve Right to Left layout of UICollectionView
in Swift
对于任何试图UICollectionView
在 Swift 中实现从右到左布局的人
//in viewDidLoad
YourCollectionView.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
//in cellForItemAtIndexPath
cell.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
回答by Robert Chen
As of iOS 9, Collection Views support RTL according to this WWDC video. So it's no longer necessary to create an RTL flow layout (unless you're already using a custom layout).
根据此WWDC 视频,从 iOS 9 开始,集合视图支持 RTL 。因此不再需要创建 RTL 流布局(除非您已经在使用自定义布局)。
Select: Edit Scheme...> Options> Run> Application Language> Right to Left Pseudolanguage
选择:编辑方案...>选项>运行>应用程序语言>从右到左伪语言
When you build to Simulator, text will be right-aligned, and your Collection View will be ordered from Right to Left.
当您构建到模拟器时,文本将右对齐,并且您的集合视图将从右到左排序。
There's a problem though. When contentOffset.x == 0
, the Collection View scroll position is at the Left
edge (wrong) instead of the Right
edge (correct). See this stack articlefor details.
不过有个问题。当 时contentOffset.x == 0
,集合视图滚动位置位于Left
边缘(错误)而不是Right
边缘(正确)。有关详细信息,请参阅此堆栈文章。
One workaround is to simply scroll the First
item to the .Left
(There's a gotcha -- .Left
is actually on the Right, or Leadingedge):
一种解决方法是简单地将First
项目滚动到.Left
(有一个问题——.Left
实际上是在Right或Lead边缘):
override func viewDidAppear(animated: Bool) {
if collectionView?.numberOfItemsInSection(0) > 0 {
let indexPath = NSIndexPath(forItem: 0, inSection: 0)
collectionView?.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Left, animated: false)
}
}
In my test project, my Collection View was nested inside a Table View Cell, so I didn't have access to viewDidAppear()
. So instead, I ended up hooking into drawRect()
:
在我的测试项目中,我的集合视图嵌套在表视图单元格中,因此我无法访问viewDidAppear()
. 所以相反,我最终连接到drawRect()
:
class CategoryRow : UITableViewCell {
@IBOutlet weak var collectionView: UICollectionView!
override func drawRect(rect: CGRect) {
super.drawRect(rect)
scrollToBeginning()
}
override func prepareForReuse() {
scrollToBeginning()
}
func scrollToBeginning() {
guard collectionView.numberOfItems(inSection: 0) > 0 else { return }
let indexPath = IndexPath(item: 0, section: 0)
collectionView.scrollToItem(at: indexPath, at: .left, animated: false)
}
}
To see this in action, check out the RTL branch on this git repo. And for context, see this blog post and its comments.
要查看此操作,请查看此 git repo 上的RTL 分支。有关上下文,请参阅此博客文章及其评论。
回答by m.alqadi
you can use this since iOS 11:
您可以从 iOS 11 开始使用它:
extension UICollectionViewFlowLayout {
open override var flipsHorizontallyInOppositeLayoutDirection: Bool {
return true
}
}
回答by cohen72
By changing bothflipsHorizontallyInOppositeLayoutDirection
and developmentLayoutDirection
, I was able to achieve a full screen RTL scroll where the first item was all the way to the right, and to reach the last cell, user will need to scroll to the left.
通过改变都flipsHorizontallyInOppositeLayoutDirection
和developmentLayoutDirection
我是能够实现全屏RTL滚动,其中第一项是一路的权利,以达到最后一个单元格,用户需要将滚动到左侧。
Like so:
像这样:
class RTLCollectionViewFlowLayout: UICollectionViewFlowLayout {
override var flipsHorizontallyInOppositeLayoutDirection: Bool {
return true
}
override var developmentLayoutDirection: UIUserInterfaceLayoutDirection {
return UIUserInterfaceLayoutDirection.rightToLeft
}
}
回答by rebello95
For anyone who has the same question:
对于任何有同样问题的人:
I ended up using the UICollectionViewRightAlignedLayout librarythat @chinttu-roxen-ramani recommended. You can either set it with code:
我最终使用了@chinttu-roxen-ramani 推荐的UICollectionViewRightAlignedLayout 库。您可以使用代码设置它:
self.collectionView.collectionViewLayout = [[UICollectionViewRightAlignedLayout alloc] init];
or through interface builder:
或通过界面构建器:
I ended up making a couple modifications to the library, but overall it works great.
我最终对库进行了一些修改,但总体来说效果很好。
回答by Mehdico
For iOS 9+
对于 iOS 9+
Reverse your collectionView in viewDidLoad()with this :
myCollectionView.transform = CGAffineTransform(scaleX: -1, y: 1)
Reverse-Back your cell (because all things is mirrored) in cellForItemAtwith this :
cell.transform = CGAffineTransform(scaleX: -1, y: 1)
使用以下方法在viewDidLoad() 中反转您的 collectionView :
myCollectionView.transform = CGAffineTransform(scaleX: -1, y: 1)
使用以下方法在cellForItemAt 中反向回退您的单元格(因为所有内容都是镜像的):
cell.transform = CGAffineTransform(scaleX: -1, y: 1)
Now content is on right side and scroll starts from right.
现在内容在右侧,滚动从右侧开始。
回答by Ashi
Non of the above answers worked for me. The main reason was that most of them are not complete. However, I found this solution from this linkby AlexSerdobintsev.
以上答案都不适合我。主要原因是它们中的大多数都不完整。然而,我发现从这个解决方案这个链接的AlexSerdobintsev。
In AppDelegate.cs. First, you have to import the following function
在 AppDelegate.cs 中。首先,您必须导入以下函数
[DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, UISemanticContentAttribute arg1);
Then call the function inside FinishedLaunching
然后调用FinishedLaunching里面的函数
var selector = new ObjCRuntime.Selector("setSemanticContentAttribute:");
IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceRightToLeft);
voila! we are done. Here is the file after applying the changes:
瞧!我们完了。这是应用更改后的文件:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
[DllImport(ObjCRuntime.Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")]
internal extern static IntPtr IntPtr_objc_msgSend(IntPtr receiver, IntPtr selector, UISemanticContentAttribute arg1);
//
// This method is invoked when the application has loaded and is ready to run. In this
// method you should instantiate the window, load the UI into it and then make the window
// visible.
//
// You have 17 seconds to return from this method, or iOS will terminate your application.
//
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.SetFlags("Shell_Experimental", "Visual_Experimental", "CollectionView_Experimental", "FastRenderers_Experimental");
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
...
var selector = new ObjCRuntime.Selector("setSemanticContentAttribute:");
IntPtr_objc_msgSend(UIView.Appearance.Handle, selector.Handle, UISemanticContentAttribute.ForceRightToLeft);
return base.FinishedLaunching(app, options);
}
}