[ios] UITableView 행 재정렬을 섹션으로 제한하는 방법
나는 이것 위에 내 머리를 치고 있었고, 구글은 아무것도 밝히지 않았다. 나는 결국 그것을 해결했고 다음 사람을 위해 여기에 쓸 것이라고 생각했습니다.
당신은이 UITableView
여러 섹션으로. 각 섹션은 동종이지만 테이블 전체는 이기종입니다. 따라서 섹션 내에서 행을 재정렬 할 수 있지만 섹션 간에는 순서를 변경할 수 없습니다 . 아마도 한 섹션 만 다시 정렬 할 수 있기를 원할 수도 있습니다 (제 경우). 내가 그랬던 것처럼에서 UITableViewDataSourceDelegate
섹션간에 행을 이동할 수있는시기에 대한 알림을 찾을 수 없습니다. 행 이동을 시작할 때 하나 (괜찮음)를 얻고 이미 이동했으면 하나를 얻고 내부 항목과 동기화 할 기회를 얻습니다. 도움이되지 않습니다.
그렇다면 섹션 간의 재정렬을 어떻게 방지 할 수 있습니까?
내가 한 일을 별도의 답변으로 게시하고 다른 사람이 더 나은 답변을 게시 할 수 있도록 열어 두겠습니다!
답변
이 구현은 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;
}
답변
정말 간단합니다.
UITableViewDelegate에는 다음 메소드가 있습니다.
tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:
사용자가 잠재적 인 드롭 포인트 위로 마우스를 가져가는 동안 호출됩니다. “아니요! 거기에 떨어 뜨리지 마십시오! 대신 여기에 떨어 뜨리십시오”라고 말할 기회가 있습니다. 제안 된 경로에 다른 색인 경로를 반환 할 수 있습니다.
내가 한 것은 섹션 인덱스가 일치하는지 확인하는 것뿐입니다. 그들이 훌륭하다면 제안 된 경로를 반환하십시오. 그렇지 않은 경우 소스 경로를 반환합니다. 이렇게하면 드래그 할 때 다른 섹션의 행이 이동하는 것을 방지 할 수 있습니다. 드래그 된 행은 다른 섹션으로 이동하려는 원래 위치로 다시 스냅됩니다.
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if( sourceIndexPath.section != proposedDestinationIndexPath.section )
{
return sourceIndexPath;
}
else
{
return proposedDestinationIndexPath;
}
}
답변
게으른 사람들을위한 Jason의 대답의 신속하고 신속한 버전 :
스위프트 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
}
스위프트 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
}
답변
아래 방법을 사용하여 구간 간 행 이동을 방지 할 수 있습니다. 섹션 사이에 어떤 움직임도 허용하지 마십시오. 섹션 내에서 특정 행의 이동을 제어 할 수도 있습니다. 예 : 섹션의 마지막 행.
다음은 그 예입니다.
- (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;
}
}
답변
스위프트 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
}
답변
@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;
}
답변
섹션 Swift3 사이의 위치를 변경하지 않는 경우
override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
if originalIndexPath.section != proposedIndexPath.section
{
return originalIndexPath
}
else
{
return proposedIndexPath
}
}