How to create custom edit menu and remove the default edit menu which is shown in pdfView for iOS 16

I am not getting any action callback on the default Highlight edit menu, when selecting the text and pressing the Highlight edit menu, where do we get the callback of this edit menu?

Also I am trying to remove this default edit menu and trying to add a set of new edit menus but some of the default edit menu is not getting removed. So how can we achieve this

Do we need to use UIEditMenuIntraction to add a new edit menu since in iOS 16 UIMenuController is deprecated, if yes then how to implement it on the text selection in pdfview.

For iOS 16 I have tried to override the default edit menus using UIMenuBuilder and added a few new edit menus as a sibling, but unable to remove the default edit menu ex-(`Highlight').

- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder{
    if (@available(iOS 16.0, *)) {
        [builder removeMenuForIdentifier:UIMenuLookup];
        [builder removeMenuForIdentifier:UIMenuReplace];
        [builder removeMenuForIdentifier:UIMenuShare];
        [builder removeMenuForIdentifier:UIMenuFormat];
        // Add new .textStyle action
        UIAction *testMenuItem = [UIAction actionWithTitle:@"Test" image:nil identifier:nil handler:^(UIAction *action){
            NSLog(@"action callback");
        }];
        [builder replaceChildrenOfMenuForIdentifier:UIMenuStandardEdit fromChildrenBlock:^NSArray<UIMenuElement *> * _Nonnull(NSArray<UIMenuElement *> * _Nonnull existingChildren) {
            NSMutableArray *children = [NSMutableArray arrayWithArray:existingChildren];
            [children addObject:testMenuItem];
            return children;
        }];
    }
    [super buildMenuWithBuilder:builder];
}

Also tried canPerformAction method to get the action callback of default Highlight edit menus and tried to the removed default edit menus by returning No but no luck.

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
  BOOL can = [super canPerformAction:action withSender:sender];
  
  return NO;
}
Post not yet marked as solved Up vote post of Swap109 Down vote post of Swap109
799 views

Replies

I have the same issue since IOS 16 and tried various ways but no luck.

It seems there is no available API to get rid of this menu at the moment.

most of the menu items are removed and a "Comment" is added import SwiftUI

struct ContentView: View { @State private var text = "Пример текста для проверки"

var body: some View {
    VStack {
        CustomTextViewRepresentable(text: $text, customMenuItems: [
            UIMenuItem(title: "Custom Action", action: #selector(CustomTextView.customAction))
        ])
        .frame(height: 200)
    }
}

}

struct CustomTextViewRepresentable: UIViewRepresentable { var text: Binding<String> var customMenuItems: [UIMenuItem]

func makeCoordinator() -> Coordinator {
    Coordinator(self)
}

func makeUIView(context: Context) -> CustomTextView {
    let textView = CustomTextView()
    textView.customMenuItems = customMenuItems
    textView.delegate = context.coordinator
    return textView
}

func updateUIView(_ uiView: CustomTextView, context: Context) {
    uiView.text = text.wrappedValue
}

class Coordinator: NSObject, UITextViewDelegate {
    var parent: CustomTextViewRepresentable

    init(_ parent: CustomTextViewRepresentable) {
        self.parent = parent
    }

    func textViewDidChange(_ textView: UITextView) {
        self.parent.text.wrappedValue = textView.text
    }
}

}

class CustomTextView: UITextView { var customMenuItems: [UIMenuItem] = []

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
            let menu = UIMenuController.shared
            let newInstanceItem = UIMenuItem(title: "Comment", action:#selector(commentThisText))
            menu.menuItems = [newInstanceItem]
            menu.update()
            if action == #selector(copy(_:)) || action == #selector(selectAll(_:)) || action == #selector(commentThisText){
                
                return true
            }
            return false
    }
    

    
    @objc func commentThisText() {
          print ("RUNNNN")
    }

override func buildMenu(with builder: UIMenuBuilder) {
    super.buildMenu(with: builder)

    for menuItem in customMenuItems {
        let action = menuItem.action
        let title = menuItem.title

        let customAction = UIAction(title: title, image: nil, identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { _ in
            self.perform(action, with: nil)
        }

        let customMenuItem = UIMenuItem(title: title, action: action)
        builder.insertChild(UIMenu(title: "", options: [], children: [customAction]), atStartOfMenu: .edit)
    }
}

@objc func customAction() {
   
    print("Custom Action")
}

}