2009-12-17 9 views

Antwort

24

Meine letzte Lösung war die folgende:

Ich habe eine Unterklasse von UILabel (UITextField sollte die gleiche Arbeit), die eine UIMenuController zeigt nach angezapft werden. CopyableLabel.m sieht wie folgt aus:

@implementation CopyableLabel 


- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 
if(action == @selector(copy:)) { 
    return YES; 
} 
else { 
    return [super canPerformAction:action withSender:sender]; 
} 
} 


- (BOOL)canBecomeFirstResponder { 
return YES; 
} 


- (BOOL)becomeFirstResponder { 
if([super becomeFirstResponder]) { 
    self.highlighted = YES; 
    return YES; 
} 
return NO; 
} 


- (void)copy:(id)sender { 
UIPasteboard *board = [UIPasteboard generalPasteboard]; 
[board setString:self.text]; 
self.highlighted = NO; 
[self resignFirstResponder]; 
} 


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
if([self isFirstResponder]) { 
    self.highlighted = NO; 
    UIMenuController *menu = [UIMenuController sharedMenuController]; 
    [menu setMenuVisible:NO animated:YES]; 
    [menu update]; 
    [self resignFirstResponder]; 
} 
else if([self becomeFirstResponder]) { 
    UIMenuController *menu = [UIMenuController sharedMenuController]; 
    [menu setTargetRect:self.bounds inView:self]; 
    [menu setMenuVisible:YES animated:YES]; 
} 
} 


@end 
+0

Diese Methode scheint nicht zu funktionieren, wenn sie innerhalb eines TableViewControllers verwendet wird, aber Sie können es funktionieren lassen, wenn Sie dies in Ihrer Ansicht hinzufügen lade 'UITapGestureRecognizer * tgr = [[UITapGestureRecognizer-Zuweisung] initWithTarget: self.yourCopyableLabel action: @selector (tapDetected) ]; [selbst.view addGestureRecognizer: tgr]; 'dann ändern Sie' - (void) touchesEnded: (NSSet *) berührt mitEvent: (UIEvent *) event' in der copyableLabel-Implementierung zu '- (void) tapDetected' und es sollte funktionieren – Fonix

+0

auch das hinzufügen 'UITapGestureRecogniser' zu einer bestimmten Zelle, wenn Sie können, die Art, wie ich oben erwähnt macht das Menü Popup, wenn Sie irgendwo auf dem Bildschirm klicken, die nicht ein anklickbares Element ist – Fonix

2

Try UITextView statt (ich vermute, dass es wie ein UILabel für Sie arbeiten würde). Getestet habe ich diese mit seiner editable Eigenschaft auf NO und Doppeltippen-to-Kopie für mich gearbeitet.

+0

Ich würde zwar vermuten, dass mit dem Feld nicht editierbar, keine Schaltfläche einfügen würde angezeigt. Lassen Sie uns wissen, ob das stimmt. – wkw

+3

Die ursprüngliche Frage ist dann nicht klar geschrieben. Ich lese "Fähigkeit zu kopieren und einzufügen", um es anderswo einzufügen. Lesen sie die andere Art und Weise, wie kann man vielleicht etwas in eine UI-Widget einfügen, die nicht * ist * editierbar? Ich glaube nicht, dass ein solches Widget existiert. –

1

Eine andere Lösung hält die UITextField aktiviert, aber programmatisch verhindern, dass es bearbeitet wird. Dies geschieht mit der folgenden Delegiertenmethode:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    return NO; 
} 

Ich bin mir nicht der möglichen Einschränkungen bewusst, aber derzeit entspricht meine Bedürfnisse.

5

Diese Frage ist ziemlich alt, und ich bin überrascht, niemand eine Lösung ohne Subclassing geschrieben hat. Die in @ mruegs Antwort vorgestellte Idee ist richtig, aber Sie sollten nichts unterlassen. Ich kam gerade über dieses Problem und löste es wie folgt aus:

In meiner Ansicht-Controller:

- (void)viewDidLoad { 
    self.textField.delegate = self; 
    self.textField.text = @"Copyable, non-editable string."; 
} 

- (BOOL)canBecomeFirstResponder { 
    return YES; 
} 

- (void)copyTextFieldContent:(id)sender { 
    UIPasteboard* pb = [UIPasteboard generalPasteboard]; 
    pb.string = self.textField.text; 
} 

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { 
    // UIKit changes the first responder after this method, so we need to show the copy menu after this method returns. 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 
     [self becomeFirstResponder]; 
     UIMenuController* menuController = [UIMenuController sharedMenuController]; 
     UIMenuItem* copyItem = [[UIMenuItem alloc] initWithTitle:@"Copy" 
                  action:@selector(copyTextFieldContent:)]; 
     menuController.menuItems = @[copyItem]; 
     CGRect selectionRect = textField.frame; 
     [menuController setTargetRect:selectionRect inView:self.view]; 
     [menuController setMenuVisible:YES animated:YES]; 
    }); 
    return NO; 
} 

Wenn Sie diese Arbeit für einen UILabel machen wollen, sollte es die gleiche Weise arbeiten mit nur einem Tippen Hinzufügen Gestenerkenner anstelle der Delegate-Methode.

0

Der folgende Code hat mich gerettet.

textField.addTarget(target, action: "textFieldEditingDidEndAction:", forControlEvents: [.EditingDidEnd]) 

Es scheint Paste ist ein einzelnes und vollständiges Bearbeitungsereignis.

0

Dadurch werden Sie alles tun müssen. Wird kopierbar sein. Aber nicht editierbar und zeigt keine Tastatur oder einen Cursor.

class ViewController: UIViewController { 

    @IBOutlet weak var copyableUneditableTextfield: UITextField! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     copyableUneditableTextfield.delegate = self 
     copyableUneditableTextfield.inputView = UIView() //prevents keyboard  
     copyableUneditableTextfield.tintColor = .clear  //prevents cursor 
     copyableUneditableTextfield.text = "Some Text You Want User To Copy But Not Edit" 

    } 

} 

extension ViewController: UITextFieldDelegate { 

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 
     return false //prevents editing 
    } 

} 
+0

Ich kann noch das Textfeld bearbeiten, auch nachdem Sie Ihren Code –

+0

@palebone tut mir leid Ich habe vergessen anzugeben, dass Sie ViewController zum Delegaten für copyableUneditableTextfield machen müssen. Ich habe den Code aktualisiert und diese Zeile hinzugefügt. – Harris

+0

Ich denke, ich habe es versucht, es ist viel einfacher, nur eine uitexview zu verwenden und es interaktiv, aber nicht bearbeitbar zu machen –

Verwandte Themen