我希望我的配件与正常情况略有不同。是否可以?此代码无效:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryView.frame = CGRectMake(5.0, 5.0, 5.0, 5.0);
我希望我的配件与正常情况略有不同。是否可以?此代码无效:
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryView.frame = CGRectMake(5.0, 5.0, 5.0, 5.0);
不,您不能移动附件视图所在的位置。作为替代方案,您可以添加如下子视图;
[cell.contentView addSubview:aView];
此外,通过将accessoryView
属性设置为等于某个值,该accessoryType
值将被忽略。
有一种方法可以移动默认的附件视图,但它非常 hacky。因此,当新的 SDK 到来时,它可能会停止工作。
使用风险自负(此代码片段accessoryView
向左移动任何 8 个像素。从所需子类[self positionAccessoryView];
的方法内部调用):-(void)layoutSubviews
UITableViewCell
- (void)layoutSubviews {
[super layoutSubviews];
[self positionAccessoryView];
}
- (void)positionAccessoryView {
UIView *accessory = nil;
if (self.accessoryView) {
accessory = self.accessoryView;
} else if (self.accessoryType != UITableViewCellAccessoryNone) {
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 isKindOfClass:[UIButton class]]) {
accessory = subview;
break;
}
}
}
CGRect r = accessory.frame;
r.origin.x -= 8;
accessory.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 给出的解决方案,我试图更好地检测附件视图,我查看了单元格的右侧。
创建一个扩展 UITableViewCell 的自定义类并添加此方法:
- (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;
}
}
}
}
也许这对你来说就足够了:
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;
通过这种方式,我在右侧添加了填充,因此附件按钮看起来向左移动。它具有更宽的区域来响应触摸,这是唯一的副作用。
在 ios 6.1 下,上述答案对我不起作用。所以我尝试使用 UIEdgeInsets,因为 DetailDisclosure 是一个 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 中可以正常工作。
对于 James Kuang,KappeaccessoryView
的默认附件视图为零。
对于 Matjan,subviews.lastObject
很容易出现错误的视图,例如 UITableViewCellSeparatorView。
对 Alexey、Ana、Tomasz 来说,枚举子视图直到我们找到一个未知的子视图。但它很费力,并且在未来的版本中很容易被打破,比如说,Apple 添加一个backgroundAccessoryView
.
对于 larshaeuser,枚举子视图直到我们找到 UIButton 是个好主意,但contentEdgeInsets
并没有充分可见地更改附件视图。
我们将枚举并查找最后一个 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
}
}
}
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
}
}
}
这是我使用的,这将摆脱默认填充。
override func layoutSubviews() {
super.layoutSubviews()
// Remove the accessory view's default padding.
accessoryView!.frame.origin.x = bounds.width - accessoryView!.bounds.width - safeAreaInsets.right
contentView.frame.size.width = bounds.width - safeAreaInsets.left - safeAreaInsets.right - accessoryView!.bounds.width
}