2009-12-17 12 views

risposta

24

La mia soluzione finale è stata la seguente:

ho creato una sottoclasse di UILabel (UITextField dovrebbe funzionare lo stesso) che visualizza un UIMenuController dopo essere stato sfruttato. CopyableLabel.m assomiglia a questo:

@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

questo metodo non sembra funzionare quando viene utilizzato all'interno di un TableViewController, ma è possibile farlo funzionare se si aggiunge questo nella vista caricata 'UITapGestureRecognizer * tgr = [[UITapGestureRecognizer alloc] initWithTarget: self.yourCopyableLabel azione: @selector (tapDetected) ]; [autonomo.visualizzare addGestureRecognizer: tgr]; 'quindi modificare' - (void) touchesEnded: (NSSet *) tocca conEvent: (UIEvent *) event' nell'implementazione copyableLabel su '- (void) tapDetected' e dovrebbe funzionare – Fonix

+0

anche aggiungere 'UITapGestureRecogniser' su una cella particolare se possibile, il modo in cui ho menzionato sopra rende il menu popup se fai clic in qualsiasi punto dello schermo che non sia un elemento cliccabile – Fonix

2

Provare invece UITextView (ho il sospetto che funzionerebbe come un UILabel per te). Ho provato questo con la sua proprietà editable impostata su NO e il doppio tocco sulla copia ha funzionato per me.

+0

Sospetto che con il campo non modificabile, non venga visualizzato alcun pulsante Incolla. Facci sapere se è vero. – wkw

+3

La domanda originale non è scritta chiaramente, quindi. Ho letto "possibilità di copiare e incollare" per significare incollarlo da qualche altra parte. Leggendolo dall'altra parte, come puoi incollare qualcosa in un widget UI che * non * è modificabile? Non penso che un tale widget esista. –

1

Un'altra soluzione è mantenere il UITextField abilitato, ma a livello di codice evitando che in fase di modifica. Questo viene fatto con il seguente metodo delegato:

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

io non sono a conoscenza di possibili limitazioni, però, attualmente adatta alle mie esigenze.

5

Questa domanda è piuttosto vecchia e sono sorpreso che nessuno abbia pubblicato una soluzione senza sottoclassi. L'idea presentata nella risposta di @ mrueg è corretta, ma non dovresti aver bisogno di sottoclasse nulla. Ho appena imbattuto in questo problema e risolto in questo modo:

A mio avviso il regolatore:

- (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; 
} 

Se si vuole fare questo lavoro per un UILabel, dovrebbe funzionare allo stesso modo con solo l'aggiunta di un tocco riconoscimento dei gesti invece di utilizzare il metodo delegato.

0

Il seguente codice mi ha salvato.

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

Sembra che Paste sia un evento di modifica singolo e completo.

0

Questo farà tutto il necessario. Sarà riproducibile Ma non modificabile e non mostrerà una tastiera o un cursore.

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

Posso ancora modificare il campo di testo anche dopo aver provato il tuo codice –

+0

@palebone sorry , Ho dimenticato di indicare che è necessario rendere ViewController il delegato per CopyableUneditableTextfield. Ho aggiornato il codice, aggiungendo quella linea. – Harris

+0

Penso di averlo provato, è molto più semplice usare uitexview e renderlo intercambiabile ma non modificabile –

Problemi correlati