Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 选中时,能否在UITableViewCell上设置高度更改动画?_Ios_Cocoa Touch_Uitableview - Fatal编程技术网

Ios 选中时,能否在UITableViewCell上设置高度更改动画?

Ios 选中时,能否在UITableViewCell上设置高度更改动画?,ios,cocoa-touch,uitableview,Ios,Cocoa Touch,Uitableview,我在iPhone应用程序中使用了UITableView,我有一个属于某个组的人的列表。我希望这样,当用户单击某个特定的人(从而选择该单元格)时,该单元格的高度会增加,以显示用于编辑该人属性的多个UI控件 这可能吗 获取所选行的索引。重新加载表格。在UITableViewDelegate的heightForRowAtIndexPath方法中,将所选行的高度设置为不同的高度,对于其他行,返回正常行高度。由于没有动画,因此重新加载数据不好 这就是我目前正在尝试的: NSArray* paths = [

我在iPhone应用程序中使用了
UITableView
,我有一个属于某个组的人的列表。我希望这样,当用户单击某个特定的人(从而选择该单元格)时,该单元格的高度会增加,以显示用于编辑该人属性的多个UI控件


这可能吗

获取所选行的索引。重新加载表格。在UITableViewDelegate的heightForRowAtIndexPath方法中,将所选行的高度设置为不同的高度,对于其他行,返回正常行高度。由于没有动画,因此重新加载数据不好

这就是我目前正在尝试的:

NSArray* paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

它几乎可以正常工作。几乎。我在增加单元格的高度,有时在替换单元格时,表格视图中会出现一些“小问题”,好像表格视图中的某些滚动位置被保留了一样,新单元格(表格中的第一个单元格)的偏移量太高,scrollview会反弹以重新定位它。

我刚刚通过一些小技巧解决了这个问题:

static int s_CellHeight = 30;
static int s_CellHeightEditing = 60;

- (void)onTimer {
    cellHeight++;
    [tableView reloadData];
    if (cellHeight < s_CellHeightEditing)
        heightAnimationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:@selector(onTimer) userInfo:nil repeats:NO] retain];
}

- (CGFloat)tableView:(UITableView *)_tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
        if (isInEdit) {
            return cellHeight;
        }
        cellHeight = s_CellHeight;
        return s_CellHeight;
}
static int s_CellHeight=30;
静态int s_CellHeightEditing=60;
-(void)onTimer{
cellHeight++;
[tableView重新加载数据];
if(单元高度

当我需要扩展单元格高度时,我设置了
isInEdit=YES
并调用该方法
[self-onTimer]
,它会使单元格生长动画化,直到达到s_CellHeightEditing值:-)

我找到了一个非常简单的解决方案,作为我正在处理的
UITableView
的副作用

将单元格高度存储在一个变量中,该变量通常通过
tableView:heightForRowAtIndexPath:
报告原始高度,然后当您想要设置高度更改的动画时,只需更改变量的值并调用此

[tableView beginUpdates];
[tableView endUpdates];
您会发现它没有完全重新加载,但足以让
UITableView
知道它必须重新绘制单元格,获取单元格的新高度值。。。。你猜怎么着?它为您设置更改的动画。好极了


我在我的博客上有更详细的解释和完整的代码示例

我喜欢西蒙·李的答案。我实际上没有尝试这种方法,但它看起来会改变列表中所有单元格的大小。我只是希望改变一下被窃听的手机。我有点像西蒙,但有点不同。这将在选定单元格时更改其外观。而且它确实有生气。只是另一种方法

创建一个int以保存当前选定单元格索引的值:

int currentSelection;
然后:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = [indexPath row];
    selectedNumber = row;
    [tableView beginUpdates];
    [tableView endUpdates];
}
然后:

我相信您可以在tableView:cellForRowAtIndexPath:中进行类似的更改,以更改单元格的类型,甚至加载单元格的xib文件


这样,currentSelection将从0开始。如果不希望列表的第一个单元格(索引0处)在默认情况下看起来是选中的,则需要进行调整。

添加一个属性以跟踪选中的单元格

@property (nonatomic) int currentSelection;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 57.0f;
    return rowHeight;
}
将其设置为(例如)
viewDidLoad
中的sentinel值,以确保
UITableView
在“正常”位置启动

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    //sentinel
    self.currentSelection = -1;
}
heightforrowatinexpath
中,可以为所选单元格设置所需的高度

@property (nonatomic) int currentSelection;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    int rowHeight;
    if ([indexPath row] == self.currentSelection) {
        rowHeight = self.newCellHeight;
    } else rowHeight = 57.0f;
    return rowHeight;
}
didselectrowatinexpath
中,保存当前选择并保存动态高度(如果需要)

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // do things with your cell here

        // set selection
        self.currentSelection = indexPath.row;
        // save height for full text label
        self.newCellHeight = cell.titleLbl.frame.size.height + cell.descriptionLbl.frame.size.height + 10;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}
didDeceloseRowatineXpath
中,将选择索引设置回sentinel值,并将单元格动画设置回正常形式

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {       
        // do things with your cell here

        // sentinel
        self.currentSelection = -1;

        // animate
        [tableView beginUpdates];
        [tableView endUpdates];
    }
}

我不知道连续调用BeginUpdate/endUpdates的所有内容是什么,您可以使用
-[UITableView reloadRowsAtIndexPaths:withAnimation:

试试这是用来展开索引行的:

@property (nonatomic) NSIndexPath *expandIndexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
if ([indexPath isEqual:self.expandedIndexPath])
    return 100;

return 44;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *modifiedRows = [NSMutableArray array];
if ([indexPath isEqual:self.expandIndexPath]) {
    [modifiedRows addObject:self.expandIndexPath];
    self.expandIndexPath = nil;
} else {
    if (self.expandedIndexPath)
        [modifiedRows addObject:self.expandIndexPath];

    self.expandIndexPath = indexPath;
    [modifiedRows addObject:indexPath];
}

// This will animate updating the row sizes
[tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];

// Preserve the deselection animation (if desired)
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ViewControllerCellReuseIdentifier];
    cell.textLabel.text = [NSString stringWithFormat:@"I'm cell %ld:%ld", (long)indexPath.section, (long)indexPath.row];

return cell;
}

我用
重新加载rowsatindexpaths
解决了这个问题

我在
didSelectRowAtIndexPath
中保存所选单元格的indexath,并在最后调用
reloadRowsAtIndexPaths
(您可以发送NSMutableArray以获取要重新加载的元素列表)

heightforrowatinexpath
中,您可以检查indexath是否在expandindexath单元格和send height的列表中

您可以检查以下基本示例: 这是一个简单的解决方案

如果有帮助,我会添加一种代码

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 20;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath*)indexPath
{
    if ([indexPath isEqual:_expandIndexPath])
        return 80;

    return 40;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Celda";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    [cell.textLabel setText:@"wopwop"];

    return cell;
}

#pragma mark -
#pragma mark Tableview Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSMutableArray *modifiedRows = [NSMutableArray array];
    // Deselect cell
    [tableView deselectRowAtIndexPath:indexPath animated:TRUE];
    _expandIndexPath = indexPath;
    [modifiedRows addObject:indexPath];

    // This will animate updating the row sizes
    [tableView reloadRowsAtIndexPaths:modifiedRows withRowAnimation:UITableViewRowAnimationAutomatic];
}

只是一个像我这样的人在自定义单元格上搜索添加“更多细节”的便条

[tableView beginUpdates];
[tableView endUpdates];
做了出色的工作,但别忘了“裁剪”单元视图。
从界面生成器中选择单元格->内容视图->从属性检查器中选择“剪辑子视图”

这是我的自定义
UITableView
子类的代码,它在表格单元格中展开
UITextView
,而无需重新加载(并丢失键盘焦点):

-(无效)textViewDidChange:(UITextView*)textView{
CGFloat textHeight=[textView SIZETATTFITS:CGSizeMake(self.width,MAXFLOAT)].height;
//如果文字高度发生变化,请检查
if(self.previousTextHeight!=textHeight&&self.previousTextHeight>0){
[自我开始更新];
//计算高差
CGFloat差值=文本高度-self.previousTextHeight;
//更新当前编辑单元格的高度
CGRect editingCellFrame=self.editingCell.frame;
editingCellFrame.size.height+=差异;
self.editingCell.frame=editingCellFrame;
//更新UITableView内容大小
self.contentSize=CGSizeMake(self.contentSize.width、self.contentSize.height+差值);
//如果单元格位于表格末尾,请滚动至底部
如果
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//This is the bit I changed, so that if tapped once on the cell, 
//cell is expanded. If tapped again on the same cell, 
//cell is collapsed. 
    if (self.currentSelection==indexPath.row) {
        self.currentSelection = -1;
    }else{
        self.currentSelection = indexPath.row;
    }
        // animate
        [tableView beginUpdates];
        [tableView endUpdates];

}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return UITableViewAutomaticDimension;
}
// MARK: - Variables 
  var isCcBccSelected = false // To toggle Bcc.



    // MARK: UITableViewDelegate
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    // Hide the Bcc Text Field , until CC gets focused in didSelectRowAtIndexPath()
    if self.cellTypes[indexPath.row] == CellType.Bcc {
        if (isCcBccSelected) {
            return 44
        } else {
            return 0
        }
    }

    return 44.0
}
  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)

    // To Get the Focus of CC, so that we can expand Bcc
    if self.cellTypes[indexPath.row] == CellType.Cc {

        if let cell = tableView.cellForRowAtIndexPath(indexPath) as? RecipientTableViewCell {

            if cell.tag == 1 {
                cell.recipientTypeLabel.text = "Cc:"
                cell.recipientTextField.userInteractionEnabled = true
                cell.recipientTextField.becomeFirstResponder()

                isCcBccSelected = true

                tableView.beginUpdates()
                tableView.endUpdates()
            }
        }
    }
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [UIView animateWithDuration:.6
                          delay:0
         usingSpringWithDamping:UIViewAnimationOptionBeginFromCurrentState
          initialSpringVelocity:0
                        options:UIViewAnimationOptionBeginFromCurrentState animations:^{

                            cellindex = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
                            NSArray* indexArray = [NSArray arrayWithObjects:indexPath, nil];
                            [violatedTableView beginUpdates];
                            [violatedTableView reloadRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationAutomatic];
                            [violatedTableView endUpdates];
                        }
                     completion:^(BOOL finished) {
    }];
}
BOOL flag;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    flag = !flag;
    [tableView beginUpdates];
    [tableView reloadRowsAtIndexPaths:@[indexPath] 
                     withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES == flag ? 20 : 40;
}
var cellIsSelected: IndexPath?


  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    cellIsSelected = cellIsSelected == indexPath ? nil : indexPath
    tableView.beginUpdates()
    tableView.endUpdates()
  }


  func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if cellIsSelected == indexPath {
      return 250
    }
    return 65
  }
tableView.beginUpdates()
tableView.endUpdates()
tableView.performBatchUpdates(nil, completion: nil)
tableView.beginUpdates()
tableView.setNeedsLayout()
tableView.endUpdates()