Мне нужно изменить значок по умолчанию для перемещения ячеек в UITableView.
Этот:
Возможно ли это?
Мне нужно изменить значок по умолчанию для перемещения ячеек в UITableView.
Этот:
Возможно ли это?
Это действительно хакерское решение, и оно может не работать в долгосрочной перспективе, но может дать вам отправную точку. Элемент управления UITableViewCellReorderControl
является UITableViewCellReorderControl
, но это частный класс, поэтому вы не можете получить к нему доступ напрямую. Однако вы можете просто просмотреть иерархию подпредставлений и найти ее imageView.
Вы можете сделать это, setEditing:animated:
подкласс UITableViewCell
и переопределив его setEditing:animated:
метод следующим образом:
- (void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing: editing animated: YES];
if (editing) {
for (UIView * view in self.subviews) {
if ([NSStringFromClass([view class]) rangeOfString: @"Reorder"].location != NSNotFound) {
for (UIView * subview in view.subviews) {
if ([subview isKindOfClass: [UIImageView class]]) {
((UIImageView *)subview).image = [UIImage imageNamed: @"yourimage.png"];
}
}
}
}
}
}
Или в Свифте
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
if editing {
for view in subviews where view.description.contains("Reorder") {
for case let subview as UIImageView in view.subviews {
subview.image = UIImage(named: "yourimage.png")
}
}
}
}
Однако будьте осторожны... это не может быть долгосрочным решением, так как Apple может изменить иерархию представлений в любое время.
Ответ Эшли Миллса был отличным в то время, когда он был предложен, но, как отмечали другие в комментариях, иерархия представлений изменилась с версии на версию iOS. Чтобы правильно найти элемент управления переупорядочением, я использую подход, который пересекает всю иерархию представлений; мы надеемся, что это даст возможность продолжить работу, даже если Apple изменит иерархию представлений.
Вот код, который я использую, чтобы найти элемент управления переупорядочением:
-(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)
{
// I'm assuming the findReorderView method noted above is either
// in the code for your subclassed UITableViewCell, or defined
// in a category for UIView somewhere
UIView *reorderView = [self findReorderView:self];
if (reorderView)
{
// I'm setting the background color of the control
// to match my cell background color
// you might need to do this if you override the
// default background color for the cell
reorderView.backgroundColor = self.contentView.backgroundColor;
for (UIView *sv in reorderView.subviews)
{
// now we find the UIImageView for the reorder control
if ([sv isKindOfClass:[UIImageView class]])
{
// and replace it with the image we want
((UIImageView *)sv).image = [UIImage imageNamed:@"yourImage.png"];
// note: I have had to manually change the image frame
// size to get it to display correctly
// also, for me the origin of the frame doesn't seem to
// matter, because the reorder control will center it
sv.frame = CGRectMake(0, 0, 48.0, 48.0);
}
}
}
}
}
Swift версия ответа Рика с небольшими улучшениями:
override func setEditing(editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
if editing {
if let reorderView = findReorderViewInView(self),
imageView = reorderView.subviews.filter({ $0 is UIImageView }).first as? UIImageView {
imageView.image = UIImage(named: "yourImage")
}
}
}
func findReorderViewInView(view: UIView) -> UIView? {
for subview in view.subviews {
if String(subview).rangeOfString("Reorder") != nil {
return subview
}
else {
findReorderViewInView(subview)
}
}
return nil
}
Обновленное решение Ashley Mills (для iOS 7.x)
if (editing) {
UIView *scrollView = self.subviews[0];
for (UIView * view in scrollView.subviews) {
NSLog(@"Class: %@", NSStringFromClass([view class]));
if ([NSStringFromClass([view class]) rangeOfString: @"Reorder"].location != NSNotFound) {
for (UIView * subview in view.subviews) {
if ([subview isKindOfClass: [UIImageView class]]) {
((UIImageView *)subview).image = [UIImage imageNamed: @"moveCellIcon"];
}
}
}
}
}
Я использую editAccessoryView для замены значка порядка.
- (void) setEditing:(BOOL)editing animated:(BOOL)animated { [super setEditing: editing animated: YES]; self.showsReorderControl = NO; self.editingAccessoryView = editing ? [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"yourReorderIcon"]] : nil; }
Если вы не используете редактирование аксессуаров, это может быть хорошим выбором.
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
for (UIControl *control in cell.subviews)
{
if ([control isMemberOfClass:NSClassFromString(@"UITableViewCellReorderControl")] && [control.subviews count] > 0)
{
for (UIControl *someObj in control.subviews)
{
if ([someObj isMemberOfClass:[UIImageView class]])
{
UIImage *img = [UIImage imageNamed:@"reorder_icon.png"];
((UIImageView*)someObj).frame = CGRectMake(0.0, 0.0, 43.0, 43.0);
((UIImageView*)someObj).image = img;
}
}
}
}
}
Swift 4
// Change default icon (hamburger) for moving cells in UITableView
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let imageView = cell.subviews.first(where: { $0.description.contains("Reorder") })?.subviews.first(where: { $0 is UIImageView }) as? UIImageView
imageView?.image = #imageLiteral(resourceName: "new_hamburger_icon") // give here your new image
imageView?.contentMode = .center
imageView?.frame.size.width = cell.bounds.height
imageView?.frame.size.height = cell.bounds.height
}
Вы также можете просто добавить свой собственный пользовательский режим переупорядочения выше всех остальных внутри вашей ячейки.
Все, что вам нужно сделать, это убедиться, что этот пользовательский вид всегда выше других, который можно проверить в [UITableViewDelegate tableView: willDisplayCell: forRowAtIndexPath: indexPath:].
Чтобы обеспечить стандартное взаимодействие управления реорганизацией, ваш пользовательский вид должен иметь свой userInteractionEnabled
установленный в НЕТ.
В зависимости от того, как выглядит ваша ячейка, вам может потребоваться более или менее сложный пользовательский режим переупорядочения (например, для имитации фона ячейки).
Я сделал это на iOS 12 с Swift 4.2
Надеюсь, это поможет:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
for view in cell.subviews {
if view.self.description.contains("UITableViewCellReorderControl") {
for sv in view.subviews {
if (sv is UIImageView) {
(sv as? UIImageView)?.image = UIImage(named: "your_image")
(sv as? UIImageView)?.contentMode = .center
sv.frame = CGRect(x: 0, y: 0, width: 25, height: 25)
}
}
}
}
}