ios 如何将 UITableView 行重新排序限制为一个部分
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/849926/
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
How to limit UITableView row reordering to a section
提问by philsquared
I was hitting my head over this one, and google was turning up nothing. I eventually worked it out and thought I'd write it up here for the sake of the next person.
我对这个问题感到头疼,而谷歌却一无所获。我最终解决了它,并认为我会为了下一个人而把它写在这里。
You have a UITableView
with multiple sections. Each section is homogeneous, but the table overall is heterogeneous. So you might want to allow re-ordering of rows within a section, but not acrosssections. Maybe you only even want want one section to be reorderable at all (that was my case).
If you're looking, as I was, at the UITableViewDataSourceDelegate
you won't find a notification for when it is about to let you move a row between sections. You get one when it starts moving a row (which is fine) and one when it's already moved it and you get a chance to sync with your internal stuff. Not helpful.
您有UITableView
多个部分。每个部分都是同质的,但表格整体是异质的。因此,您可能希望允许在一个部分内重新排序行,但不允许跨部分重新排序。也许您甚至只想要一个部分可以重新排序(这就是我的情况)。如果您像我一样正在查看,UITableViewDataSourceDelegate
您将找不到有关何时让您在部分之间移动一行的通知。当它开始移动一行时你会得到一个(这很好),当它已经移动它并且你有机会与你的内部内容同步时你会得到一个。没有帮助。
So how can you prevent re-orders between sections?
那么如何防止部分之间的重新排序呢?
I'll post what I did as a separate answer, leaving it open for someone else to post an even better answer!
我会将我所做的作为单独的答案发布,让其他人发布更好的答案!
回答by Jason Harwig
This implementation will prevent re-ordering outside of the original section like Phil's answer, but it will also snap the record to the first or last row of the section, depending on where the drag went, instead of where it started.
这种实现将防止像 Phil 的回答那样在原始部分之外重新排序,但它也会将记录对齐到该部分的第一行或最后一行,具体取决于拖动的位置,而不是它的开始位置。
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
NSInteger row = 0;
if (sourceIndexPath.section < proposedDestinationIndexPath.section) {
row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1;
}
return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];
}
return proposedDestinationIndexPath;
}
回答by philsquared
Simple enough, really.
很简单,真的。
The UITableViewDelegate has the method:
UITableViewDelegate 有方法:
tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:
This gets called while the user is hovering over a potential drop point. You get a chance to say, "no! don't drop it there! Drop it over here instead". You can return a different index path to the proposed one.
当用户将鼠标悬停在潜在的放置点上时,它会被调用。你有机会说,“不!不要把它扔在那里!把它扔在这里”。您可以将不同的索引路径返回到建议的索引路径。
All I did was check if the section indices match. If they do then great, return the proposed path. if not, return the source path. This also nicely prevents the rows in other sections even moving out of the way as you drag - and the dragged row will snap back to it's original position of you try to move it to another section.
我所做的只是检查部分索引是否匹配。如果他们做得很好,请返回建议的路径。如果没有,则返回源路径。这也很好地防止了其他部分中的行甚至在您拖动时移开 - 当您尝试将其移动到另一个部分时,拖动的行将弹回到它的原始位置。
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if( sourceIndexPath.section != proposedDestinationIndexPath.section )
{
return sourceIndexPath;
}
else
{
return proposedDestinationIndexPath;
}
}
回答by Alexander of Norway
Swifty swift version of Jason's answer for you lazy people:
杰森为你懒惰的人回答的快速版本:
Swift 3, 4 & 5
斯威夫特 3、4 和 5
override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
if sourceIndexPath.section != proposedDestinationIndexPath.section {
var row = 0
if sourceIndexPath.section < proposedDestinationIndexPath.section {
row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1
}
return IndexPath(row: row, section: sourceIndexPath.section)
}
return proposedDestinationIndexPath
}
Swift 1 & 2
斯威夫特 1 & 2
override func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
if sourceIndexPath.section != proposedDestinationIndexPath.section {
var row = 0
if sourceIndexPath.section < proposedDestinationIndexPath.section {
row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1
}
return NSIndexPath(forRow: row, inSection: sourceIndexPath.section)
}
return proposedDestinationIndexPath
}
回答by Henry
Swift 3:
斯威夫特 3:
override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
if sourceIndexPath.section != proposedDestinationIndexPath.section {
var row = 0
if sourceIndexPath.section < proposedDestinationIndexPath.section {
row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1
}
return IndexPath(row: row, section: sourceIndexPath.section)
}
return proposedDestinationIndexPath
}
回答by Andy
You can prevent the movement of rows in between section using below method. Just do not allow any movement in between section. You can even control the movement of specific row within a section. e.g last row in a Section.
您可以使用以下方法防止部分之间的行移动。只是不允许在部分之间有任何移动。您甚至可以控制某个部分内特定行的移动。例如,节中的最后一行。
Here is the example:
这是示例:
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
// Do not allow any movement between section
if ( sourceIndexPath.section != proposedDestinationIndexPath.section) {
return sourceIndexPath;
}
// You can even control the movement of specific row within a section. e.g last row in a Section
// Check if we have selected the last row in section
if (sourceIndexPath.row < sourceIndexPath.length) {
return proposedDestinationIndexPath;
}
else {
return sourceIndexPath;
}
}
回答by Bkillnest
Than @Jason Harwig, the code below works correctly.
比@Jason Harwig,下面的代码可以正常工作。
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
NSInteger row = 0;
if (sourceIndexPath.section < proposedDestinationIndexPath.section) {
row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1;
}
return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];
}
return proposedDestinationIndexPath;
}
回答by ayalcin
For not changing position between sections Swift3
为了不改变Swift3部分之间的位置
override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
if originalIndexPath.section != proposedIndexPath.section
{
return originalIndexPath
}
else
{
return proposedIndexPath
}
}