标准配件视图可以在UitableViewCell中处于不同的位置吗?
-
03-10-2019 - |
题
我希望我的配件与正常情况略有不同。可能吗?该代码没有效果:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryView.frame = CGRectMake(5.0, 5.0, 5.0, 5.0);
解决方案
不,您无法移动附件视图所在。作为替代方案,您可以添加一个子视图,如以下内容;
[cell.contentView addSubview:aView];
另外,通过设置 accessoryView
属性等于某物, accessoryType
值被忽略。
其他提示
有一种方法可以移动默认的cockestoryView,但这很骇人听闻。因此,当新的SDK到达时,它可能停止工作。
自行使用(此代码摘要移动任何 accessoryView
左侧8像素。将其插入 -(void)layoutSubviews
所需的方法 UITableViewCell
子类):
if (self.accessoryView) {
r = self.accessoryView.frame;
r.origin.x -= 8;
self.accessoryView.frame = r;
} else {
UIView *defaultAccessoryView = nil;
for (UIView *subview in self.subviews) {
if (subview != self.textLabel &&
subview != self.detailTextLabel &&
subview != self.backgroundView &&
subview != self.contentView &&
subview != self.selectedBackgroundView &&
subview != self.imageView) {
defaultAccessoryView = subview;
break;
}
}
r = defaultAccessoryView.frame;
r.origin.x -= 8;
defaultAccessoryView.frame = r;
}
我只需在我的自定义单元子类中执行此操作即可更改附件视图的框架。
CGRect adjustedFrame = self.accessoryView.frame;
adjustedFrame.origin.x += 10.0f;
self.accessoryView.frame = adjustedFrame;
另一种方法是将您的自定义附件视图嵌入另一个视图中,该视图将其设置为单元格视图,并使用框架控制填充。
这是一个带有图像视图作为自定义附件视图的示例:
// Use insets to define the padding on each side within the wrapper view
UIEdgeInsets insets = UIEdgeInsetsMake(24, 0, 0, 0);
// Create custom accessory view, in this case an image view
UIImage *customImage = [UIImage imageNamed:@"customImage.png"];
UIImageView *accessoryView = [[UIImageView alloc] initWithImage:customImage];
// Create wrapper view with size that takes the insets into account
UIView *accessoryWrapperView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, customImage.size.width+insets.left+insets.right, customImage.size.height+insets.top+insets.bottom)];
// Add custom accessory view into wrapper view
[accessoryWrapperView addSubview:accessoryView];
// Use inset's left and top values to position the custom accessory view inside the wrapper view
accessoryView.frame = CGRectMake(insets.left, insets.top, customImage.size.width, customImage.size.height);
// Set accessory view of cell (in this case this code is called from within the cell)
self.accessoryView = accessoryWrapperView;
遵循ANA给出的解决方案,我尝试更好地检测附件视图,我在单元格的右侧查看。
创建一个扩展uitaiteViewCell并添加此方法的自定义类:
- (void)layoutSubviews {
[super layoutSubviews];
if (self.accessoryType != UITableViewCellAccessoryNone) {
float estimatedAccesoryX = MAX(self.textLabel.frame.origin.x + self.textLabel.frame.size.width, self.detailTextLabel.frame.origin.x + self.detailTextLabel.frame.size.width);
for (UIView *subview in self.subviews) {
if (subview != self.textLabel &&
subview != self.detailTextLabel &&
subview != self.backgroundView &&
subview != self.contentView &&
subview != self.selectedBackgroundView &&
subview != self.imageView &&
subview.frame.origin.x > estimatedAccesoryX) {
// This subview should be the accessory view, change its frame
frame = subview.frame;
frame.origin.x -= 10;
subview.frame = frame;
break;
}
}
}
}
以上答案在iOS 6.1下对我不起作用。因此,我尝试使用uiedgeinsets,因为细节披露是uibutton。而且现在正常工作。这里的来源:
if (cell.accessoryType == UITableViewCellAccessoryDetailDisclosureButton) {
UIView* defaultAccessoryView = [cell.subviews lastObject];
if ([defaultAccessoryView isKindOfClass:[UIButton class]]){
UIButton *bt = (UIButton*)defaultAccessoryView;
bt.contentEdgeInsets = UIEdgeInsetsMake(0, 0, 0, 10);
}
}
设置一个简单的方法 自定义位置 为了 附件 那是 坚持任何单元状态 是在layoutsubviews中布局辅助视图:
- (void)layoutSubviews
{
[super layoutSubviews];
self.accessoryView.center = CGPointMake($yourX, $yourY);
}
我正在与iOS5合作,而Alexey提供的解决方案并非完全工作。我发现,当辅助类型设置在表上时,辅助视图为无效,因此第一个“如果”不起作用。我只是更改了代码:
if (self.accessoryType != UITableViewCellAccessoryNone) {
UIView* defaultAccessoryView = nil;
for (UIView* subview in self.subviews) {
if (subview != self.textLabel &&
subview != self.detailTextLabel &&
subview != self.backgroundView &&
subview != self.contentView &&
subview != self.selectedBackgroundView &&
subview != self.imageView &&
subview != self.explanationButton && // Own button
subview.frame.origin.x > 0 // Assumption: the checkmark will always have an x position over 0.
) {
defaultAccessoryView = subview;
break;
}
}
r = defaultAccessoryView.frame;
r.origin.x -= 8;
defaultAccessoryView.frame = r;
}
这个解决方案对我有用。正如Alexey所说,我不知道将来的版本会发生什么,但至少在iOS 4中正在工作。
也许这对您来说足够了:
UIImageView* accessoryImageView = [[UIImageView alloc] initWithFrame:
CGRectMake(0, 0, accessoryImage.size.width + MARGIN_RIGHT, accessoryImage.size.height)];
accessoryImageView.contentMode = UIViewContentModeLeft;
accessoryImageView.image = accessoryImage;
self.accessoryView = accessoryImageView;
这样,我向右添加了填充物,因此附件按钮看起来向左移动。它具有响应触摸的更宽区域,这是唯一的副作用。
改进其他答案
对于James Kuang,Kappe, accessoryView
为默认配件视图而零。
对于Matjan, subviews.lastObject
很容易看错视图,就像uitaiteViewCellSeParatorView一样。
对于Alexey,Ana,Tomasz,列举了子视图,直到我们找到一个未知的作品。但这很费力,如果苹果添加了一个 backgroundAccessoryView
.
对于Larshaeuser来说 contentEdgeInsets
没有充分明显地更改附件视图。
Swift 3.x和4.0的解决方案
我们将列举并寻找最后的Uibutton。
class AccessoryTableViewCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
if let lastButton = subviews.reversed().lazy.flatMap({ $0 as? UIButton }).first {
// This subview should be the accessory view, change its origin
lastButton.frame.origin.x = bounds.size.width - lastButton.frame.size.width - 5
}
}
}
对于Swift 4.1和更新
class AccessoryTableViewCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
// https://stackoverflow.com/a/45625959/1033581
if let lastButton = subviews.reversed().lazy.compactMap({ $0 as? UIButton }).first {
// This subview should be the accessory view, change its origin
lastButton.frame.origin.x = bounds.size.width - lastButton.frame.size.width - 5
}
}
}