当UITableView处于编辑模式时,有没有办法更改重新排序控件显示的图像?我有一张UIImage想要显示,而不是通常的灰色条。
我必须子类化UITableViewCell才能实现这个目的吗?
当UITableView处于编辑模式时,有没有办法更改重新排序控件显示的图像?我有一张UIImage想要显示,而不是通常的灰色条。
我必须子类化UITableViewCell才能实现这个目的吗?
最近我遇到了需要更改重新排序控件图像的需求,因为我子类化了UITableViewCell
以提供自己的自定义表格单元。为此,我将单元格的背景更改为与默认颜色不同的颜色。
一切都正常工作,但当我将UITableView
设置为编辑模式时,重新排序控件会出现白色背景 - 而不是我用于单元格的背景颜色。这看起来不好,我希望背景匹配。
在各个iOS版本中,UITableViewCell
中的视图层次结构已经发生了变化。我采取了一种方法,将遍历整个视图集,直到找到UITableViewCellReorderControl
私有类。我相信这将适用于iOS 5和所有随后的iOS版本(截至本答案发布时)。请注意,尽管UITableViewCellReorderControl
类本身是私有的,但我没有使用任何私有API来查找它。
首先,这里是扫描重新排序控件的代码;我假设文本“Reorder”将出现在类名中 - 这是苹果未来可能会更改的内容:
-(UIView *) findReorderView:(UIView *) view
{
UIView *reorderView = nil;
for (UIView *subview in view.subviews)
{
if ([[[subview class] description] rangeOfString:@"Reorder"].location != NSNotFound)
{
reorderView = subview;
break;
}
else
{
reorderView = [self findReorderView:subview];
if (reorderView != nil)
{
break;
}
}
}
return reorderView;
}
-(void) setEditing:animated:
方法,并在此处查找重新排序控件。如果您尝试在表格不处于编辑模式时查找此控件,则重新排序控件不会出现在该单元格的视图层次结构中。-(void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
if (editing)
{
// find the reorder view here
// place the previous method either directly in your
// subclassed UITableViewCell, or in a category
// defined on UIView
UIView *reorderView = [self findReorderView:self];
if (reorderView)
{
// here, I am changing the background color to match my custom cell
// you may not want or need to do this
reorderView.backgroundColor = self.contentView.backgroundColor;
// now scan the reorder control's subviews for the reorder image
for (UIView *sv in reorderView.subviews)
{
if ([sv isKindOfClass:[UIImageView class]])
{
// and replace the image with one that you want
((UIImageView *)sv).image = [UIImage imageNamed:@"yourImage.png"];
// it may be necessary to properly size the image's frame
// for your new image - in my experience, this was necessary
// the upper left position of the UIImageView's frame
// does not seem to matter - the parent reorder control
// will center it properly for you
sv.frame = CGRectMake(0, 0, 48.0, 48.0);
}
}
}
}
}
可能会因人而异;希望这对你有用。
这是基于Rick Morgan答案的Swift解决方案:
func adjustSize() {
// we're trying to leverage the existing reordering controls, however that means the table must be kept in editing mode,
// which shrinks the content area to less than full width to make room for editing controls
let cellBounds = bounds
let contentFrame = contentView.convert(contentView.bounds, to: self)
let leftPadding = contentFrame.minX - cellBounds.minX
let rightPadding = cellBounds.maxX - contentFrame.maxX
// adjust actual content so that it still covers the full length of the cell
contentLeadingEdge.constant = -leftPadding
// this should pull our custom reorder button in line with the system button
contentTrailingEdge.constant = -rightPadding
// make sure we can still see and interact with the content that overhangs
contentView.clipsToBounds = false
// recursive search of the view tree for a reorder control
func findReorderControl(_ view: UIView) -> UIView? {
// this is depending on a private API, retest on every new iPad OS version
if String(describing: type(of: view)).contains("Reorder") {
return view
}
for subview in view.subviews {
if let v = findReorderControl(subview) {
return v
}
}
return nil
}
// hunt down the system reorder button and make it invisible but still operable
findReorderControl(self)?.alpha = 0.05 // don't go too close to alpha 0, or it will be considered hidden
}
contentLeadingEdge
和 contentTrailingEdge
是我在Interface Builder中设置的布局约束,用于contentView
和实际内容之间。我的代码从tableView(_:willDisplay:forRowAt:)
委托方法中调用adjustSize
方法。awakeFromNib
中直接向单元格添加了UIImageView(而不是contentView
),将其定位,并且当调用adjustSize
时,我只需将图像视图置于前端即可,它就可以覆盖重新排序控件,而无需依赖任何私有API。最近我花了一些时间在这个问题上,但是没有得到解决。我尝试设置自己的editingAccessoryView,但无法改变重新排序控件。很奇怪。
我猜测这可能与UITableviewCell文档中关于showsReorderControl的以下注释有关:
如果值为YES,则重新排序控件会暂时替换任何附加视图。
换句话说,编辑附件视图被重新排序控件视图替换,这可能是我们无法覆盖重新排序控件的原因。希望有人能找到解决方法。
您可以将单元格的 editingAccessoryView
属性设置为包含所需图像的图像视图。
顺便提一句,当您这样做时,请注意小心。当您用自定义图像代替重新排序图形等系统标准时,存在严重混淆用户的风险。标准 UI 语法告诉他们在重新排序时期望标准图形,他们可能不理解您自定义图像的意义。
cell.editingAccessoryType = UITableViewCellEditingStyleNone;
但没有用。 - Raphael SchweikertUITableViewCellAccessoryDetailDisclosureButton
,否则编辑附件视图将不会出现或响应。请阅读UITableView文档以获取详细信息。 - TechZenUIImageView
放在默认移动附件的顶部,以覆盖它。完成。