Ios 在UITableViewCell中,标准附件视图是否可以位于不同的位置?

Ios 在UITableViewCell中,标准附件视图是否可以位于不同的位置?,ios,objective-c,iphone,uitableview,accessoryview,Ios,Objective C,Iphone,Uitableview,Accessoryview,我希望我的配件在一个稍微不同的地方比正常。可能吗? 此代码无效: cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; cell.accessoryView.frame = CGRectMake(5.0, 5.0, 5.0, 5.0); 不,您不能移动附件视图所在的位置。作为替代方案,您可以添加一个子视图,如下所示: [cell.contentView addSubview:aView]; 另外,通过将acces

我希望我的配件在一个稍微不同的地方比正常。可能吗? 此代码无效:

cell.accessoryType =  UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryView.frame = CGRectMake(5.0, 5.0, 5.0, 5.0);

不,您不能移动附件视图所在的位置。作为替代方案,您可以添加一个子视图,如下所示:

[cell.contentView addSubview:aView];

另外,通过将
accessoryView
属性设置为某物,将忽略
accessoryType
值。

有一种方法可以移动默认的accessoryView,但这是一种非常粗糙的方法。因此,有一天当新SDK出现时,它可能会停止工作

自担风险使用(此代码段将任何
accessoryView
8像素向左移动。从所需
UITableViewCell
子类的
-(void)LayoutSubview
方法内部调用
[self-positionAccessoryView];
):


我当时正在处理ios5,Alexey给出的解决方案并不完全有效。我发现在表上设置accessoryType时,accessoryView为null,因此第一个“if”不起作用。我对代码做了一些修改:

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中是有效的。

按照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);
    }
}

我可以通过在自定义单元格子类中简单地更改附件视图的框架

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;

为在任何单元格状态下保持的辅助视图设置自定义位置的简单方法是在布局子视图中布局辅助视图:

- (void)layoutSubviews
{
    [super layoutSubviews];
    self.accessoryView.center = CGPointMake($yourX, $yourY);
}
其他答案的改进 对于James Kuang,Kappe,
accessoryView
对于默认附件视图为零

对于Matjan,
子视图.lastObject
很容易是错误的视图,就像UITableViewCellSeparator视图一样

对于Alexey、Ana、Tomasz来说,枚举子视图直到我们找到一个未知的子视图暂时有效。但是,如果苹果公司增加了一个
backgroundAccessoryView
,那么它很难在未来的版本中被打破

对于larshaeuser来说,枚举子视图直到找到一个UIButton是个好主意,但是
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及更新版本
这里是我使用的,这将摆脱默认的填充

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
}

谢谢我想使用披露指示符的原因是,选中该行时,该指示符变为白色。似乎没有办法在选择单元格后立即更改accessoryView。确实可以通过编程方式移动附件视图,方法是覆盖布局子视图并调整框架,如@Incyc的答案所示。appstore应用程序是否合法?有人成功地使用了它吗?它没有使用任何私有api,因此是合法的。我使用了它,我的应用程序被成功批准。另一方面,你必须明白它也不是公共API的一部分,因此它可以随时停止工作。我的应用程序也通过了验证。Hide hack:)谢谢Alexey,我为你的代码添加了更多的逻辑。在下面找到我的解决方案。这很好。今晚它节省了我的时间。我很感激。谢谢安娜,我给你的代码添加了更多的逻辑,以找到我在单元格右侧看到的附件视图。它很有效。如果有人想尝试这个答案,请将这些代码行放入子类
layoutSubviews
方法中;另外,不要忘记在
layoutSubviews
方法的开头调用
[super layoutSubviews]
。对于默认附件视图,
accessoryView
为零,因此您没有回答问题。对于默认附件视图,
accessoryView
为零,因此您没有回答问题。@Cœu什么?:D阅读原始问题,你的评论没有任何意义。试试看,在objC中,
cell.accessoryType=uitableviewcellaccessorydeposureindicator然后
NSLog(@“%@”,cell.accessoryView)
您将看到问题中的代码为什么不起作用,或者您的代码为什么也不起作用。这也解释了最重要的两个答案。
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
}