我有一个占据广告位的人员名单。我希望用户能够将这些人重新安排到不同的位置,但是,有些地方是不受限制的。我认为使用UITableView的重新排列功能最容易实现。但是,我无法弄清楚如何保持我不可用的地方不稳定。
例如,我想将Activia Boulanger移到第5位。灰色细胞应该是不可移动的细胞。
开始观点:
UITableView自动执行的操作:
我想要UITableView做什么:
设置tableView:canMoveRowAtIndexPath:
似乎只是阻止您移动细胞,但不会阻止细胞移动以响应其他细胞的移动。
非常感谢任何帮助。 感谢
更新: 下面是一些示例代码,其中包含问题的设置。我没有把我的努力包括在一个解决方案中,因为它们都失败了并且会使事情变得混乱。
#import "LDYViewController.h"
static NSString * unmoveableCellId = @"NoMove";
static NSString * moveableCellId = @"OkMove";
@implementation LDYViewController
@synthesize tableView;
@synthesize peopleList;
- (void)viewDidLoad
{
[super viewDidLoad];
peopleList = [[NSMutableArray alloc] initWithObjects:
@"Belinda Boomer", @"Activia Boulanger", @"Arnold Carter", [NSNull null], @"Attila Creighton", [NSNull null], @"Bruce Cleary", [NSNull null], nil];
[tableView setEditing:YES];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return peopleList.count;
}
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if([peopleList objectAtIndex:indexPath.row] == [NSNull null]) {
cell = [tableView dequeueReusableCellWithIdentifier:unmoveableCellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:unmoveableCellId];
cell.userInteractionEnabled = NO;
cell.contentView.backgroundColor = [UIColor grayColor];
}
} else {
cell = [tableView dequeueReusableCellWithIdentifier:moveableCellId];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:moveableCellId];
NSString * name = [peopleList objectAtIndex:indexPath.row];
cell.textLabel.text = name;
}
}
return cell;
}
- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
}
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
return proposedDestinationIndexPath;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
if([peopleList objectAtIndex:indexPath.row] == [NSNull null]) {
return NO;
}
return YES;
}
@end
答案 0 :(得分:8)
试试这个:
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath*)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
你可以查看proposedDestinationIndexPath,如果你不想将行移动到它,你可以返回sourceIndexPath然后行将被移回,否则返回proposalDestinationIndexPath。
答案 1 :(得分:2)
我遇到了类似的问题并解决了它。
创建2部分并将所有灰色行放在第2部分中。
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath{
if (proposedDestinationIndexPath.section == 1)
return sourceIndexPath;
else
return proposedDestinationIndexPath;
}
答案 2 :(得分:2)
在模型上执行正常的重新排列逻辑,然后在完成后,将空值放回到您想要的位置。发布的代码不包括模型,所以这里有一个合理的模型来说明:
// always leave our array with a null at indexes 3,5,7
// i'm sure you have better logic about where nulls go, but just to illustrate
- (void)addNulls {
NSMutableArray *answer = [NSMutableArray array];
for (id object in self.peopleList) {
if (![object isKindOfClass:[NSNull self]]) {
[answer addObject:object];
}
}
assert(answer.count >= 4);
[answer insertObject:[NSNull null] atIndex:3];
[answer insertObject:[NSNull null] atIndex:5];
[answer insertObject:[NSNull null] atIndex:7];
self.peopleList = answer;
}
// build a pretend model with nulls
- (NSMutableArray *)peopleList {
if (!_peopleList) {
_peopleList = [NSMutableArray array];
[_peopleList addObject:@"Moe"];
[_peopleList addObject:@"Larry"];
[_peopleList addObject:@"Curly"];
[_peopleList addObject:[NSNull null]];
[_peopleList addObject:@"Groucho"];
[_peopleList addObject:[NSNull null]];
[_peopleList addObject:@"Chico"];
[_peopleList addObject:[NSNull null]];
[_peopleList addObject:@"Harpo"];
}
return _peopleList;
}
// normal rearrange logic, then fix your array up
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
// reorder the list with the typical logic, ignoring nulls
NSString *stringToMove = [self.peopleList objectAtIndex:fromIndexPath.row];
[self.peopleList removeObjectAtIndex:fromIndexPath.row];
[self.peopleList insertObject:stringToMove atIndex:toIndexPath.row];
// now put nulls into the positions you want them
[self addNulls];
[self.tableView reloadData];
}
答案 3 :(得分:0)
您可以使用以下方法执行此操作:
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{
在此方法中,您需要检查from indexIndexPath和toIndexPath以检查用户是否正在移动到无效位置。修改tableview的数据源,将单元格放回或移动到正确的位置。
答案 4 :(得分:0)
Swift Implementation
class TableViewMovable: UITableView, UITableViewDelegate, UITableViewDataSource {
var arrDataSource = [[String:Int]]()
override func awakeFromNib() {
super.awakeFromNib()
commonInit()
}
func commonInit(){
dataSource = self
delegate = self
isEditing = true
register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrDataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "cell") {
cell.textLabel?.text = arrDataSource[indexPath.row].keys.first!
let val = arrDataSource[indexPath.row].values.first!
cell.backgroundColor = val % 2 == 0 ? UIColor.gray.withAlphaComponent(0.5) : UIColor.lightGray.withAlphaComponent(0.5)
return cell
}else{
return UITableViewCell()
}
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return .none
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let movedObject = arrDataSource[sourceIndexPath.row]
arrDataSource.remove(at: sourceIndexPath.row)
arrDataSource.insert(movedObject, at: destinationIndexPath.row)
debugPrint("\(sourceIndexPath.row) => \(destinationIndexPath.row)")
}
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
}
Hope this might help someone.