简体   繁体   English

旋转自定义UITableViewCell

[英]Rotate a custom UITableViewCell

I have a custom UITableViewCell which contains several UIButtons. 我有一个包含几个UIButton的自定义UITableViewCell。 Each button's frame position is relative to the cell width. 每个按钮的框架位置都相对于单元格宽度。 I set autoresizingMask=UIViewAutoresizingFlexibleWidth so it will adjust the cell width and the button positions properly when the application starts with the device either in landscape or portrait mode. 我设置了autoresizingMask = UIViewAutoresizingFlexibleWidth,这样当应用程序以横向或纵向模式启动设备时,它将正确调整单元格宽度和按钮位置。

The issue is when the device is rotated from one mode to the other, the buttons do not adjust positions because the UITableViewCell is reusable. 问题是当设备从一种模式旋转到另一种模式时,按钮无法调整位置,因为UITableViewCell可重复使用。 In other words, the cell is not initialized based on the new UITalbeView width because the cell's function initWithStyle is called before the device is rotated and is not called again after the device rotation. 换句话说,单元格不会基于新的UITalbeView宽度进行初始化,因为单元格的函数initWithStyle在设备旋转之前被调用,而在设备旋转之后不再被调用。 Any suggestions? 有什么建议么?

Since UITableViewCell is also a UIView, you can override setFrame method. 由于UITableViewCell也是UIView,因此可以重写setFrame方法。 Everytime that your table view rotates, this method will be called for all cells. 每次表格视图旋转时,所有单元格都会调用此方法。

-(void)setFrame:(CGRect)frame
{
    [super setFrame:frame];

    //Do your rotation stuffs here :)
} 

After spending hours of research (including posts in this site), I could not find any solutions. 经过数小时的研究(包括本网站上的帖子),我找不到任何解决方案。 But a light bulb turns on all of a sudden. 但是灯泡突然打开了。 The solution is very simple. 解决方案非常简单。 Just detect whether the device orientation is landscape or portrait mode and define the ReusableCellIdentifier with a different name for each. 只需检测设备方向是横向还是纵向,然后为ReusableCellIdentifier定义一个不同的名称即可。

static NSString*Identifier;

if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight) {
                Identifier= @"aCell_portrait";
            }
            else Identifier= @"DocumentOptionIdentifier_Landscape";


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];

Previous answer has a serious problem. 先前的答案存在严重问题。 You should use [UIApplication sharedApplication].statusBarOrientation instead of [UIDevice currebtDevice].orientation because Device orientation has nothing to do with interface orientation - Device orientation is physical rotation based on accelerometer. 您应该使用[UIApplication sharedApplication] .statusBarOrientation而不是[UIDevice currebtDevice] .orientation,因为设备方向与界面方向无关-设备方向是基于加速度计的物理旋转。

The ticked answer works like a charm in old iOS versions. 被打勾的答案在旧的iOS版本中就像一个魅力。 For iOS 6.0 I used the next code: 对于iOS 6.0,我使用了以下代码:

static NSString *Identifier;
if (self.interfaceOrientation==UIInterfaceOrientationPortrait) {
    Identifier=@"aCell_portrait";
}
else {
    Identifier=@"DocumentOptionIdentifier_Landscape";
}

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];

You'll need to fix your cells frame width (assuming the height is same in portrait and landscape mode) within your cellForRowAtIndexPath method. 您需要在cellForRowAtIndexPath方法中修复单元格的框架宽度(假设纵向和横向模式下的高度相同)。 That is what is working here. 那就是这里的工作。 I used to create a custom TableViewCell with IB and it is always initialised for portrait 320 px width. 我曾经用IB创建自定义TableViewCell,并且始终将其初始化为纵向320 px宽度。 With defining the frame it works as expected, even if the cell is "reused" from queue. 通过定义帧,即使从队列中“重用”单元格,它也可以按预期工作。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 ...
 UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
 if (cell == nil) {
    // create cell here...
 }

 // Adjust cell frame width to be equal to tableview frame width
 cell.frame = CGRectMake(0, 0, tableView.frame.size.width, cell.frame.size.height);
 ...
}

I had a similar problem and this post helped me. 我有一个类似的问题,这篇文章对我有所帮助。 In my case I have a custom class declared in a separate file, and in this file I have the following code in layoutSubviews : 就我而言,我在一个单独的文件中声明了一个自定义类,在这个文件中,我在layoutSubviews具有以下代码:

//PORTRAIT CELL
if ([UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeLeft && 
    [UIDevice currentDevice].orientation!=UIDeviceOrientationLandscapeRight)
{
    //build the custom content views for portrait mode here
}
else
{
    //build the custom content views for landscape mode here
}

Then in my view controller I just implement willAnimateRotationToInterfaceOrientation: and send the reloadData message to my table view. 然后,在我的视图控制器中,我只实现willAnimateRotationToInterfaceOrientation:并将reloadData消息发送到我的表视图。

With this I don't have to touch the cellForRow method. 有了这个,我不必触摸cellForRow方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM