2012-02-02 25 views
74

我正在製作一個UITextField,它的UIPickerViewinputView。它的一切都很好,除了我可以通過複製,粘貼,剪切和選擇文本進行編輯,而且我不需要它。只有選取器應該修改文本字段。如何禁用UITextField編輯,但仍然接受觸摸?

我知道我可以通過將setEnabledsetUserInteractionEnabled:NO設置爲NO來禁用編輯。好的,但TextField停止響應觸摸和選取器不顯示。

我能做些什麼來實現它?

+0

嘿,我想知道你是如何實現的一個UIPickerView爲您inputView?你有代碼示例嗎?目前我讓我的UIPickerView像彈出一樣從底部出現。我寧願讓它像鍵盤一樣出現。你如何設置你的框架等? – 2015-10-06 15:50:15

回答

103

使用文本框的委託,有一個方法

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 

不返回從此,任何試圖通過用戶編輯文本將被拒絕。

通過這種方式,您可以啓用該字段,但仍會阻止人們將文本粘貼到該字段中。

+4

如果您仍然想回應觸摸,請回復「觸摸」而不是「觸摸」。否則你的事件永遠不會被調用。 – radven 2012-05-29 18:52:27

+0

@NickLockwood有什麼方法可以讓我們仍然允許textField成爲第一響應者,但禁用用戶交互並隱藏插入符號? – onmyway133 2014-02-26 04:03:40

+1

@entropy我假設你想能夠選擇內容,以便用戶可以複製它?如果你繼承UITextField,你可以重寫任何行爲 - 例如您可以強制該字段在用戶觸摸時始終選擇所有字段,這將有效隱藏插入符號。 – 2014-02-27 11:36:21

0

此變通辦法適用。把上面的文本字段透明的UIView和執行下面的代碼:

- (void)viewDidLoad 
{ 
[super viewDidLoad]; 

    UILongPressGestureRecognizer *press = [[UILongPressGestureRecognizer alloc]    initWithTarget:self action:@selector(longPress)]; 
[transparentView addGestureRecognizer:press]; 
[press release]; 
    press = nil; 
} 

-(void)longPress 
{ 
    txtField.userInteractionEnabled = NO; 
} 

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    txtField.userInteractionEnabled = YES; 
} 

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [txtField becomeFirstResponder]; 
} 
+0

我很困惑你爲什麼不使用簡單的透明UIButton + touchUpInside,而是選擇了UIView +手勢。 – 2017-10-09 01:43:47

5

這將是更優雅創造UITextField自定義子類,返回NO所有調用canPerformAction:withSender:(或至少在action@selector(cut)@selector(paste)),如here所述。

此外,我還希望實現 - (BOOL)文本框:(的UITextField *)文本框shouldChangeCharactersInRange:(NSRange)範圍replacementString:(的NSString *)字符串 按照尼克的建議,以禁止從藍牙輸入文本鍵盤。

+0

不能爲我的生活制定出如何做到這一點。從不調用子類的'canPerformAction'和'shouldChangeCharactersInRange'方法。 – Nestor 2014-03-28 11:36:25

17

這將是最簡單的是:

在viewDidLoad中

:(僅適用於文本框不應該是可編輯設置委託

self.textfield.delegate=self; 

,並插入此委託功能:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ 
return NO; 
} 

那就是它!

+17

這可以防止選擇器被呈現,所以不能解決所描述的問題 – 2013-11-10 14:25:28

+3

@MartinLockett如果您從該委託方法中觸發「UIPickerView」行爲,它可以很好地工作。 – 2015-01-03 00:59:33

-3

我用過:

[self.textField setEnabled:NO]; 

其做工精細

0

讓您inputView通過隱藏的文本字段這也改變了介紹和禁用一個的文本呈現。

1

對於處理UIPickerView和行動表,結賬ActionSheetPicker

https://github.com/TimCinel/ActionSheetPicker

這是啓用的CocoaPods的替代品。它處理操作表中的所有取消和完成按鈕。示例項目中的示例非常棒。我選擇了ActionSheetStringPicker,它很容易處理基於String的選項,但API可以處理大部分我能想到的事情。

我最初開始很像勾選答案的解決方案,但無意中發現了這個項目,並花了我大約20分鐘即可到達的東西整合到應用中的使用,包括使用cocopods:ActionSheetPicker(〜> 0.0)

希望這有助於。

下載Git項目,並期待在以下類:

  • ActionSheetPickerViewController.m
  • ActionSheetPickerCustomPickerDelegate.h

這裏是最粗略我添加的代碼,再加上* .h進口。

- (IBAction)gymTouched:(id)sender { 
     NSLog(@"gym touched"); 

     [ActionSheetStringPicker showPickerWithTitle:@"Select a Gym" rows:self.locations initialSelection:self.selectedIndex target:self successAction:@selector(gymWasSelected:element:) cancelAction:@selector(actionPickerCancelled:) origin:sender]; 
} 


- (void)actionPickerCancelled:(id)sender { 
    NSLog(@"Delegate has been informed that ActionSheetPicker was cancelled"); 
} 


- (void)gymWasSelected:(NSNumber *)selectedIndex element:(id)element { 
    self.selectedIndex = [selectedIndex intValue]; 

    //may have originated from textField or barButtonItem, use an IBOutlet instead of element 
    self.txtGym.text = [self.locations objectAtIndex:self.selectedIndex]; 
} 


-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField { 
    return NO; // Hide both keyboard and blinking cursor. 
} 
+0

現在比使用這個動作表包裝器更好地使用內置功能。例如UIPickerView作爲inputView和一個按鈕欄作爲inputAccessoryView – malhal 2018-01-15 21:32:56

4

只需將一個UIButton正是在整個的UITextField沒有標籤的文本,這使得它「隱形」。此按鈕可以接收和委託觸摸而不是文本框,並且TextField的內容仍然可見。

+0

此解決方案適用於我的情況 – WBuck 2018-02-12 12:12:56

1

我使用了MrMage提供的解決方案。我唯一要補充的是你應該將UITextView作爲第一響應者辭職,否則你會被選中的文本卡住。

這裏是我的SWIFT代碼:

class TouchableTextView : UITextView { 

    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool { 
     self.resignFirstResponder() 
     return false 
    } 

    override func shouldChangeTextInRange(range: UITextRange, replacementText text: String) -> Bool { 
     self.resignFirstResponder() 
     return false 
    } 

} 
0

要防止的UITextField的編輯,同時使用UIPickerView選擇值(SWIFT):

self.txtTransDate = self.makeTextField(self.transDate, placeHolder: "Specify Date") 
self.txtTransDate?.addTarget(self, action: "txtTransDateEditing:", forControlEvents: UIControlEvents.EditingDidBegin) 

func makeTextField(text: String?, placeHolder: String) -> UITextField { 
    var textField = UITextField(frame: CGRect(x: 140, y: 0, width: 220.00, height: 40.00)); 
    textField.placeholder = placeHolder 
    textField.text = text 
    textField.borderStyle = UITextBorderStyle.Line 
    textField.secureTextEntry = false; 
    textField.delegate = self 
    return textField 
} 


func txtTransDateEditing(sender: UITextField) { 
    var datePickerView:UIDatePicker = UIDatePicker() 
    datePickerView.datePickerMode = UIDatePickerMode.Date 
    sender.inputView = datePickerView 
    datePickerView.addTarget(self, action: Selector("datePickerValueChanged:"), forControlEvents: UIControlEvents.ValueChanged) 
} 

func datePickerValueChanged(sender: UIDatePicker) { 
    var dateformatter = NSDateFormatter() 
    dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle 
    self.txtTransDate!.text = dateformatter.stringFromDate(sender.date) 
} 

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    self.resignFirstResponder() 
    return false 
} 
6

尼克答案翻譯成迅速:

P/S:返回false =>文本框不能輸入,用鍵盤編輯。它只是可以通過code.EX設置文本:的TextField.text =「我的字符串這裏」

override func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { 
    return false 
} 
+2

這對我不起作用。只需長按文本字段,直到出現縮放並出現iOS剪切/複製/粘貼菜單,我可以使用它來改變文本。 – RowanPD 2016-07-20 13:53:49

+0

SWIFT 4: ' FUNC文本框(_文本框:的UITextField,shouldChangeCharactersIn範圍:NSRange,replacementString字符串:字符串) - >布爾{ 返回假 } ' – lionello 2018-01-23 05:08:57

-6

這爲我工作 [textview setEditable:NO]; 以上答案是過於複雜的情況。

+1

的OP中寫道:「我知道我可以通過設置禁止編輯setEnabled或setUserInteractionEnabled:NO到NO。Ok,但TextField停止響應觸摸並且選取器不顯示。「你的回答將會阻止所有的事件,這不是預期的結果。 – maninvan 2015-10-01 06:21:00

+0

@Tolgab不是這個OP的相關解決方案! – 2017-05-22 12:41:37

5

在斯威夫特:

func textFieldShouldBeginEditing(textField: UITextField) -> Bool { 
    questionField.resignFirstResponder(); 
    // Additional code here 
    return false 
} 
1

在迅速3+:

class MyViewController: UIViewController, UITextFieldDelegate { 

    override func viewDidLoad() { 
     self.myTextField.delegate  = self 
    } 

    func textFieldShouldBeginEditing(textField: UITextField) -> Bool { 
     if textField == myTextField { 
     // code which you want to execute when the user touch myTextField 
     } 
     return false 
    } 
} 
相關問題