旋转自定义 UITableViewCell

发布于 2024-08-26 00:13:00 字数 315 浏览 17 评论 0原文

我有一个自定义 UITableViewCell,其中包含几个 UIButton。每个按钮的框架位置都相对于单元格宽度。我设置了 autoresizingMask=UIViewAutoresizingFlexibleWidth,以便当应用程序以横向或纵向模式的设备启动时,它将正确调整单元格宽度和按钮位置。

问题是当设备从一种模式旋转到另一种模式时,按钮不会调整位置,因为 UITableViewCell 是可重用的。换句话说,单元格不会根据新的 UITalbeView 宽度进行初始化,因为单元格的函数 initWithStyle 在设备旋转之前被调用,并且在设备旋转之后不会再次调用。有什么建议吗?

I have a custom UITableViewCell which contains several UIButtons. 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.

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. 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. Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

海未深 2024-09-02 00:13:00

由于 UITableViewCell 也是一个 UIView,因此您可以重写 setFrame 方法。每次表格视图旋转时,都会为所有单元格调用此方法。

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

    //Do your rotation stuffs here :)
} 

Since UITableViewCell is also a UIView, you can override setFrame method. 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 :)
} 
思念绕指尖 2024-09-02 00:13:00

经过几个小时的研究(包括本网站上的帖子),我找不到任何解决方案。但灯泡突然亮了。解决方案非常简单。只需检测设备方向是横向还是纵向模式,并为每个方向定义不同名称的 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];

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.

static NSString*Identifier;

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


    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
居里长安 2024-09-02 00:13:00

之前的回答有一个严重的问题。
您应该使用 [UIApplication sharedApplication].statusBarOrientation 而不是 [UIDevice currebtDevice].orientation,因为设备方向与界面方向无关 - 设备方向是基于加速度计的物理旋转。

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.

始终不够爱げ你 2024-09-02 00:13:00

勾选的答案在旧的 iOS 版本中就像一个魅力。对于 iOS 6.0,我使用了以下代码:

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];

The ticked answer works like a charm in old iOS versions. For iOS 6.0 I used the next code:

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

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
把人绕傻吧 2024-09-02 00:13:00

您需要在 cellForRowAtIndexPath 方法中修复单元格框架宽度(假设纵向和横向模式下的高度相同)。这就是这里的工作原理。我曾经使用 IB 创建自定义 TableViewCell,并且它始终初始化为纵向 320 px 宽度。通过定义框架,即使单元从队列中“重用”,它也会按预期工作。

- (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);
 ...
}

You'll need to fix your cells frame width (assuming the height is same in portrait and landscape mode) within your cellForRowAtIndexPath method. 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. 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);
 ...
}
呢古 2024-09-02 00:13:00

我遇到了类似的问题,这篇文章对我有帮助。就我而言,我在单独的文件中声明了一个自定义类,在该文件中,我在 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
}

然后在我的视图控制器中,我只需实现 willAnimateRotationToInterfaceOrientation:并将 reloadData 消息发送到我的表视图。

这样我就不必接触 cellForRow 方法。

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:

//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.

With this I don't have to touch the cellForRow method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文