Я хочу, чтобы мой аксессуар находился в немного другом месте, чем обычно. Является ли это возможным? Этот код не действует:
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 игнорируется.
Есть способ переместить defaultксессуар, но он довольно взломан. Таким образом, он может перестать работать в один прекрасный день, когда придет новый 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 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;
}
}
}
}
Вышеуказанные ответы не помогли мне в соответствии с 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);
}
}
Я работал с ios5, и решение, данное Алексеем, не работало полностью. Я обнаружил, что, когда в таблице установлен атрибут accessoriesType, accessView имеет значение null, поэтому первое "если" не работает. Я немного изменил код:
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;
}
и это решение работает для меня. Как сказал Алексей, я не знаю, что произойдет с будущими версиями, но, по крайней мере, в 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;
Таким образом, я добавил прописку справа, так что кнопка аксессуаров смещается влево. Он имеет более широкую область, которая реагирует на касания, это единственный побочный эффект.
Простым способом установки настраиваемой позиции для аксессуара, который сохраняется в любом состоянии ячейки, является расположение аксессуара в layoutSubViews:
- (void)layoutSubviews
{
[super layoutSubviews];
self.accessoryView.center = CGPointMake($yourX, $yourY);
}
Для Джеймса Куанга, Kappe, accessoryView нет нулевого значения для аксессуаров по умолчанию.
Для Matjan, subviews.lastObject легко выглядит неправильно, например, UITableViewCellSeparatorView.
Для Алексея, Ана, Томаша, перечисляющего подпункты, пока мы не найдем неизвестного, сейчас работает. Но это кропотливо и может быть легко сломано в будущих версиях, если, скажем, 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
}
}
}