在自定义UITableViewCell中更改自定义UIButton的位置

时间:2011-12-02 06:24:36

标签: iphone objective-c ios ipad

我需要动态更改UIButton的位置。我在cellForRowAtIndexPath:中执行此操作。我改变了该方法中按钮的框架。最初显示表时不显示更改。但是,当我滚过细胞并回到它时,它会显示出来。同样,当我第一次滚动到最初不可见的单元格时,没有任何变化。当我第二次滚动到它时发生了变化。

我在自定义按钮和表格视图上都尝试了setNeedsDisplay:。我甚至在willDisplayCell:forRowAtIndexPath:中也这样做了。我该如何解决这个问题?

编辑:我忘了提到我正在从nib文件加载UITableViewCell。这是调整框架大小的代码。

label1.text  = //text from some source
label1.text = [label1.text stringByAppendingString:@"  |"];
[label1 sizeToFit];
CGRect frameAfterResize=label1.frame;
float x=frameAfterResize.origin.x+frameAfterResize.size.width;
button.frame=CGRectMake(x+2, button.frame.origin.y, button.frame.size.width,button.frame.size.height);

7 个答案:

答案 0 :(得分:6)

创建自己的UITableViewCell子类。在init方法中创建单元格的contentView并将其添加到单元格中,或者通过访问者属性创建并添加它。覆盖layoutSubviews并根据需要设置按钮。

这样的事情:

@implementation MyCustomCell

- (void) init
{
    self = [super initWithStyle: UITableViewCellStyleDefault reuseIdentifier: nil];
    if ( self != nil )  
    {
         _myButton = [[UIButton buttonWithType: UIButtonTypeRoundedRect] retain];
         [self.contentView addSubview: _myButton];
    }

    return self;
}

- (void) layoutSubviews
{
    [super layoutSubviews];

    // dynamic layout logic:
    if ( ... )
    {

         _myButton.frame = CGRectMake( 10, 10, 100, 30 );
    }
    else 
   {
         _myButton.frame = CGRectMake( 20, 10, 50, 30 );

   }
}

或者,您可以尝试在- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

中进行单元格布局

答案 1 :(得分:3)

我有同样的问题,我从笔尖加载单元格,但上述解决方案都没有完全适合我。他们在很少的场景中解决了这个问题,但并非全部解决了。

以下是适用于所有情况的解决方案。

@implementation MyChannelCell
-(void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    //Calling from here fixed issue for first time cell load
    [self alignCellViews];
}
-(void)layoutSubviews
{
    [super layoutSubviews];
    //Calling from here fixed issue for coming back to the tableview from other ViewConroller
    [self alignCellViews];

}
/**
Method to change the layout and positions of sub-views
*/
-(void)alignCellViews
{
    //Code to position sub-views
    //self.lblSubscribers is an outlet from nib of type UILabel
    [self.lblSubscribers setFrame:CGRectMake(140, 26, 36, 26)];

    [self setNeedsDisplay];
}

@end

答案 2 :(得分:1)

您是否尝试使用

更改单元格的框架后重新加载表格
[self.tableView reloadData]

我认为它可以解决你的问题。

答案 3 :(得分:1)

  1. 制作您自己的UITableViewCell子类
  2. 将所有插座(按钮也从xib连接到此类
  3. 例如,在这个UITableViewCell子类中创建自定义方法 - 见下文,不能在那里格式化。
  4. cellForRowAtIndexPath中的
  5. :使用此方法更改框架和重绘单元格

    [cell setNewFrame:....];

  6. 它适用于我

     -(void)setNewFrame:(CGRect)newFrame
        {
            myButton.frame=newFrame;
            [self setNeedsDisplay];
        }
    

    如果您想将按钮调整为文字

    -(void)setNewCaption:(NSString)newCaption
    {
      label1.text  = newCaption
      label1.text = [label1.text stringByAppendingString:@"  |"];
      // calculate new frame
      myButton.frame=//new frame
      [self setNeedsDiplay];
    }
    

答案 4 :(得分:0)

使用setNeedsDisplay对象调用UITableViewCell

[cell setNeedsDisplay];
cellForRowAtIndexPath:

中的

答案 5 :(得分:0)

如果它最初没有按要求显示,但是在滚动后没有显示,那么我的猜测是你只在单元格出列时改变标签位置,而不是在最初从笔尖加载时。

你还没有给出你的cellForRowAtIndexPath方法的这部分,所以我暂时不能给出任何更具体的建议,但是上面的代码没有被执行,或者当一个新的单元格被创建时label1是nil (即,当dequeue方法返回nil并从nib加载时)。

答案 6 :(得分:0)

在绘制UITableViews时,表单元格被重用,因此只有一个UITableViewCell实例被传递给dequeueReusableCellWithIdentifier的字符串标识:。

如果更新cellForRowAtIndexPath:方法中的单元格,它将不会产生您期望的效果 - 每次您将引用相同的单元格(因此每个单元格将使按钮处于相同位置)。因此,您看到滚动使按钮改变位置的问题。

解决问题的最简单方法是通过在cellForRowAtIndexPath中每次创建一个新单元来更改代码以停止重复使用单元格。像这样更新代码:

// comment out this line
// cell = [tableView dequeueReusableCellWithIdentifier:identifier];

NSArray *nib = [[NSBundle mainBundle] loadNibNamed:nibName];
cell = [nib objectAtIndex:0];

请注意,尽管出于效率原因(为了节省内存和减少内存分配),首选重复使用单元格。

您理想的解决方案是创建UITableViewCell的自定义子类,并在layoutSubviews方法中更新UIButton的位置。