简体   繁体   中英

UITableViewRowAction is too wide in iOS 11

I use the following trick in order to have images in table view row actions:

How to manage equal width for UITableViewRowAction in iOS8.0?(More,Delete,etc actions)

UITableViewRowAction *completeAction = [UITableViewRowAction
                                        rowActionWithStyle:UITableViewRowActionStyleNormal
                                        title:@"   "
                                        handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
                                            ...
                                        }];
completeAction.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"MyImageHere"]];

but it no longer works with iOS 11 - the width of the row action button is too big for my image so it's repeated:

截图

Is there a fix for this?

Update:

I ended up using the new trailing / leading contextual actions API introduced in iOS 11:

https://developer.apple.com/documentation/uikit/uicontextualaction

This API allows you to have images in actions and more.

#if defined __IPHONE_11_0 && __has_builtin(__builtin_available)

// This will be called on iOS 11+ if compiling with Xcode 9.

- (id)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (@available(iOS 11.0, *)) {
        UISwipeActionsConfiguration *configuration = ...
        return configuration;
    }
    return nil;
}

#endif

// This will be called on iOS 10 and older.

- (NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView
                  editActionsForRowAtIndexPath:(NSIndexPath *)indexPath {
    // Old style row actions.
}

Be aware that if you compile code like this with Xcode 8 the new delegate method will not be defined (and you will see the bug).

I had the same problem and was able to fix it. However, my solution is quite hacky and needs some explanation:

We'll have to implement an own UITableView , which modifies the layout of it's subviews and subsubviews in LayoutSubviews() . The view that contains the action buttons is a UISwipeActionPullView and is a subview. This type is not available at compile time (maybe someone knows how to check for this type?), but we can check for the type UIKit.UIView and check if the view has the same amount of subviews ( UIButton ) as we defined action buttons.

We want to avoid our subview to get wider than the sum of widths of our action buttons. In that case we need to fix the size and position of our UISwipeActionPullView . Furthermore we need to fix the positioning of the UIButton .

My code gives an example for three fixed width action buttons:

class CustomTableView: UITableView
{
    public CustomTableView(CGRect frame, UITableViewStyle style) : base(frame, style)
    {
    }

    public override void LayoutSubviews()
    {
        base.LayoutSubviews();
        var buttonSize = 54;

        foreach (var actionView in Subviews)
        {
            if (actionView.GetType().FullName == "UIKit.UIView" && actionView.Subviews.Length == 3)
            {
                if (actionView.Frame.Width >= buttonSize* 3)
                {
                    actionView.Frame = new CGRect(Frame.Width - 3 * buttonSize, actionView.Frame.Y, buttonSize* 3, buttonSize);
                    int i = 0;
                    foreach (var button in actionView.Subviews)
                    {
                        button.Frame = new CGRect(i * buttonSize, 0, buttonSize, buttonSize);
                        i++;
                    }
                }
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM