IB의 라이브러리에서 소개는 return키를 누르면 키보드 UITextView
가 사라질 것임을 알려줍니다 . 그러나 실제로 return키는 '\ n'으로 만 작동 할 수 있습니다.
버튼을 추가 [txtView resignFirstResponder]
하고 키보드를 숨기는 데 사용할 수 있습니다 .
그러나 return키보드에 키에 대한 작업을 추가하여 추가 할 필요가없는 방법이 UIButton
있습니까?
IB의 라이브러리에서 소개는 return키를 누르면 키보드 UITextView
가 사라질 것임을 알려줍니다 . 그러나 실제로 return키는 '\ n'으로 만 작동 할 수 있습니다.
버튼을 추가 [txtView resignFirstResponder]
하고 키보드를 숨기는 데 사용할 수 있습니다 .
그러나 return키보드에 키에 대한 작업을 추가하여 추가 할 필요가없는 방법이 UIButton
있습니까?
답변:
UITextView
사용자가 리턴 키를 눌렀을 때 호출되는 메소드가 없습니다. 사용자가 한 줄의 텍스트 만 추가 할 수있게하려면을 사용하십시오 UITextField
. 리턴을 치고 키보드를 숨기는 UITextView
것은 인터페이스 지침을 따르지 않습니다.
그럼에도 불구 하고이 작업을 수행하려는 경우 대체 텍스트가 있는지 확인하고 해당 확인 textView:shouldChangeTextInRange:replacementText:
방법을 구현하십시오.UITextViewDelegate
\n
인 하고 키보드를 숨기십시오.
다른 방법이있을 수 있지만 나는 전혀 모른다.
[textField setReturnKeyType: UIReturnKeyDone];
인터페이스 빌더를 사용하거나 인터페이스 빌더를 사용 하여 리턴 키를 "완료"로 쉽게 변경할 수 있습니다.
대신 스 니펫을 여기에 게시 할 것이라고 생각했습니다.
UITextViewDelegate
프로토콜에 대한 지원을 선언해야합니다 .
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
스위프트 4.0 업데이트 :
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
나는 이것이 이미 대답되었다는 것을 알고 있지만 실제로 줄 바꿈에 문자열 리터럴을 사용하는 것을 좋아하지 않으므로 여기에 내가 한 일이 있습니다.
- (BOOL)textView:(UITextView *)txtView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if( [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location == NSNotFound ) {
return YES;
}
[txtView resignFirstResponder];
return NO;
}
스위프트 4.0 업데이트 :
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if (text as NSString).rangeOfCharacter(from: CharacterSet.newlines).location == NSNotFound {
return true
}
txtView.resignFirstResponder()
return false
}
NSString *replacedText = [textView.text stringByReplacingCharactersInRange:range withString:text]
.
나는 이것이 여러 번 대답되었다는 것을 알고 있지만 여기 에이 문제에 대한 2 센트가 있습니다.
나는 대답을 찾았다. samvermette 및 ribeto 정말 유용하고, 또한 의해 코멘트 maxpower 에서 ribeto 의 대답을. 그러나 이러한 접근 방식에는 문제가 있습니다. samvermette 에서 매트가 언급 한 문제 의 대답 는 사용자가 줄 바꿈으로 무언가를 붙여 넣으려면 키보드를 붙여 넣지 않고 숨길 수 있다는 것입니다.
그래서 내 접근 방식은 위에서 언급 한 세 가지 솔루션의 혼합이며 문자열 길이가 1 일 때 입력 한 문자열이 새 줄인지 확인하므로 붙여 넣지 않고 입력하는 것을 확인합니다.
여기 내가 한 일이 있습니다.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
NSRange resultRange = [text rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet] options:NSBackwardsSearch];
if ([text length] == 1 && resultRange.location != NSNotFound) {
[textView resignFirstResponder];
return NO;
}
return YES;
}
보다 우아한 방법은 사용자가 키보드 프레임 바깥 쪽을 누를 때 키보드를 닫는 것입니다.
먼저 UIBuilder의 자격 증명 관리자에서 ViewController의보기를 "UIControl"클래스로 설정하십시오. 보기를 ViewController의 헤더 파일로 Control- 드래그하고 Touch Up Inside와 같은 이벤트와 같은 동작으로 연결하십시오.
ViewController.h
-(IBAction)dismissKeyboardOnTap:(id)sender;
기본 ViewController 파일에서 ViewController.m :
-(IBAction)dismissKeyboardOnTap:(id)sender
{
[[self view] endEditing:YES];
}
유사한 기술을 사용하여 두 번 누르거나 길게 터치해야 할 수 있습니다. ViewController를 UITextViewDelegate로 설정하고 TextView를 ViewController에 연결해야 할 수도 있습니다. 이 메서드는 UITextView와 UITextField 모두에 적용됩니다.
출처 : 빅 얼간이 목장
편집 : 또한 UIScrollView를 사용하는 경우 위의 기술이 Interface Builder를 통해 쉽게 작동하지 않을 수 있다고 덧붙이고 싶습니다. 이 경우 UIGestureRecognizer를 사용하고 대신 [[self view] endEditing : YES] 메소드를 호출 할 수 있습니다. 예를 들면 다음과 같습니다.
-(void)ViewDidLoad{
....
UITapGestureRecognizer *tapRec = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(tap:)];
[self.view addGestureRecognizer: tapRec];
....
}
-(void)tap:(UITapGestureRecognizer *)tapRec{
[[self view] endEditing: YES];
}
사용자가 키보드 외부를 두드리고 입력 공간을 두드리지 않으면 키보드가 사라집니다.
GestureRecognizer
하지만 큰 문제는보기의 모든 버튼이나 컨트롤을 더 이상 클릭 할 수 없다는 것입니다.
이 메소드를 뷰 컨트롤러에 추가하십시오.
스위프트 :
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
return false
}
return true
}
이 방법도 도움이 될 수 있습니다.
/**
Dismiss keyboard when tapped outside the keyboard or textView
:param: touches the touches
:param: event the related event
*/
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
if let touch = touches.anyObject() as? UITouch {
if touch.phase == UITouchPhase.Began {
textField?.resignFirstResponder()
}
}
}
super.touchesBegan(touches:withEvent:)
.
else { return true }
.
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if([text isEqualToString:@"\n"])
[textView resignFirstResponder];
return YES;
}
yourtextView.delegate=self;
또한 추가 UITextViewDelegate
프로토콜을 확인하는 것을 잊지 마십시오
추가 if([text isEqualToString:@"\n"])
하지 않으면 편집 할 수 없습니다
NO
text가 같으면 돌아 오는 것을 놓쳤다 @"\n"
.
uitextview와 함께 사용하는 동안 다른 해결 방법이 있습니다. "textViewShouldBeginEditing"에서 도구 모음을 InputAccessoryView로 추가 할 수 있으며이 도구 모음의 완료 단추에서 키보드를 닫을 수 있습니다. 이에 대한 코드는 다음과 같습니다.
viewDidLoad에서
toolBar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)]; //toolbar is uitoolbar object
toolBar.barStyle = UIBarStyleBlackOpaque;
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(btnClickedDone:)];
[toolBar setItems:[NSArray arrayWithObject:btnDone]];
textviewdelegate 메소드에서
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
[textView setInputAccessoryView:toolBar];
return YES;
}
툴바에있는 버튼 완료의 동작은 다음과 같습니다.
-(IBAction)btnClickedDone:(id)sender
{
[self.view endEditing:YES];
}
josebama 의 답변 이이 스레드에서 사용할 수있는 가장 완전하고 깨끗한 답변 이라는 것을 알았 습니다.
다음은 Swift 4 구문입니다.
func textView(_ textView: UITextView, shouldChangeTextIn _: NSRange, replacementText text: String) -> Bool {
let resultRange = text.rangeOfCharacter(from: CharacterSet.newlines, options: .backwards)
if text.count == 1 && resultRange != nil {
textView.resignFirstResponder()
// Do any additional stuff here
return false
}
return true
}
resultRange
텍스트는 하드 코드 "\ n"을 방지 개행 문자가 포함되어 있는지 여부를 테스트하는 것을 목표로하고있다.
빠른
func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
textView.resignFirstResponder()
}
return true
}
탐색 컨트롤러를 사용하여 바를 호스팅하여 키보드를 닫습니다.
.h 파일에서 :
UIBarButtonItem* dismissKeyboardButton;
.m 파일에서 :
- (void)viewDidLoad {
dismissKeyboardButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissKeyboard)];
}
-(void)textViewDidBeginEditing:(UITextView *)textView {
self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}
-(void)textFieldDidBeginEditing:(UITextField *)textField {
self.navigationItem.rightBarButtonItem = dismissKeyboardButton;
}
-(void)dismissKeyboard {
[self.textField resignFirstResponder];
[self.textView resignFirstResponder];
//or replace this with your regular right button
self.navigationItem.rightBarButtonItem = nil;
}
samvermette에 대한 무언의 주석처럼 "\ n"도 감지하는 것을 좋아하지 않습니다. UITextView에는 "return"키가 있습니다. 즉, 다음 줄로 넘어갑니다.
제 생각에 가장 좋은 해결책은 키보드에 도구 모음 (및 버튼)을 추가하는 iPhone 메시지 앱을 모방하는 것입니다.
다음 블로그 게시물에서 코드를 얻었습니다.
http://www.iosdevnotes.com/2011/02/iphone-keyboard-toolbar/
단계 :
XIB 파일에 툴바 추가-높이를 460으로 설정
도구 모음 버튼 항목을 추가합니다 (아직 추가하지 않은 경우). 오른쪽 정렬이 필요한 경우 유연한 막대 버튼 항목을 XIB에 추가하고 도구 모음 버튼 항목을 이동하십시오.
다음과 같이 버튼 항목을 resignFirstResponder에 연결하는 조치를 작성하십시오.
- (IBAction)hideKeyboard:(id)sender {
[yourUITextView resignFirstResponder];
}
-그때:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.view.frame.size.height - 260.0;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
- (void)keyboardWillHide:(NSNotification *)notification {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.view.frame.size.height;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
이 문제를 다른 방식으로 해결했습니다.
컨트롤을 버튼을 viewController.h
파일로 드래그하고 다음 과 같은 액션 (Sent Event : Touch Up Inside)을 만듭니다.
(IBAction)ExitKeyboard:(id)sender;
에서이 ViewController.m
같이해야한다 :
(IBAction)ExitKeyboard:(id)sender {
[self.view endEditing:TRUE];
}
viewDidLoad에 옵저버 추가
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(textViewKeyPressed:) name: UITextViewTextDidChangeNotification object: nil];
그런 다음 셀렉터를 사용하여 "\ n"을 확인하십시오.
-(void) textViewKeyPressed: (NSNotification*) notification {
if ([[[notification object] text] hasSuffix:@"\n"])
{
[[notification object] resignFirstResponder];
}
}
"\ n"을 사용하고 특별히 리턴 키를 확인하지는 않지만 이것이 정상이라고 생각합니다.
최신 정보
아래 [NSCharacterSet newlineCharacterSet]
대신 사용하는 ribto의 답변을 참조하십시오.\n
\n
하고 리턴 키를 기준으로 감지 \n
하므로 리턴 키를 확인합니다. 유일한 차이점은 textViewDelegates를 사용하지 않고 알림을 사용한다는 것입니다.
[NSCharacterSet newlineCharacterSet]
\ n 대신 확인하는 것이 더 좋은 방법 이라고 생각 합니다.
스위프트 코드
클래스 / 뷰에서 UITextViewDelegate를 구현하십시오.
class MyClass: UITextViewDelegate { ...
textView 델리게이트를 self로 설정
myTextView.delegate = self
그런 다음 다음을 구현하십시오.
func textViewDidChange(_ textView: UITextView) {
if textView.text.characters.count >= 1 {
if let lastChar = textView.text.characters.last {
if(lastChar == "\n"){
textView.text = textView.text.substring(to: textView.text.index(before: textView.text.endIndex))
textView.resignFirstResponder()
}
}
}
}
편집 텍스트 필드의 사용자 입력을 해결 방법으로 변경하고 해킹 코드가 완료 된 후 상태를 재설정하지 않는 것이 좋기 때문에 코드를 업데이트했습니다.
// 이것을 사용할 수 있습니다 ...
1 단계. 첫 번째 단계는 UITextViewDelegate
프로토콜 지원을 선언하는 것입니다 . 이것은 헤더 파일에서 수행되며 예를 들어 헤더는
EditorController.h :
@interface EditorController : UIViewController {
UITextView *messageTextView;
}
@property (nonatomic, retain) UITextView *messageTextView;
@end
2 단계. 다음으로 컨트롤러를 UITextView의 대리자로 등록해야합니다. 위의 예에서 계속해서 , 대리인으로 UITextView
with EditorController
를 초기화하는 방법은 다음 과 같습니다.
- (id) init {
if (self = [super init]) {
// define the area and location for the UITextView
CGRect tfFrame = CGRectMake(10, 10, 300, 100);
messageTextView = [[UITextView alloc] initWithFrame:tfFrame];
// make sure that it is editable
messageTextView.editable = YES;
// add the controller as the delegate
messageTextView.delegate = self;
}
3 단계. 이제 퍼즐의 마지막 부분은 shouldCahngeTextInRange
다음과 같이 메시지 에 응답하여 조치를 취하는 것입니다 .
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
// Any new character added is passed in as the "text" parameter
if ([text isEqualToString:@"\n"]) {
// Be sure to test for equality using the "isEqualToString" message
[textView resignFirstResponder];
// Return FALSE so that the final '\n' character doesn't get added
return FALSE;
}
// For any other character return TRUE so that the text gets added to the view
return TRUE;
}
보기 화면에서 터치 할 때 키보드를 숨길 수도 있습니다.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * touch = [touches anyObject];
if(touch.phase == UITouchPhaseBegan) {
[txtDetail resignFirstResponder];
}
}
신속한 답변 :
override func viewDidLoad() {
super.viewDidLoad()
let tapGestureReconizer = UITapGestureRecognizer(target: self, action: "tap:")
view.addGestureRecognizer(tapGestureReconizer)
}
func tap(sender: UITapGestureRecognizer) {
view.endEditing(true)
}
이 코드를 사용하여 응답자를 변경했습니다.
- (BOOL)textView:(UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text
{
if ([text isEqualToString:@"\n"]) {
//[textView resignFirstResponder];
//return YES;
NSInteger nextTag = textView.tag + 1;
// Try to find next responder
UIResponder* nextResponder = [self.view viewWithTag:nextTag];
if (nextResponder) {
// Found next responder, so set it.
[nextResponder becomeFirstResponder];
} else {
// Not found, so remove keyboard.
[textView resignFirstResponder];
}
return NO;
return NO;
}
return YES;
}
질문은 리턴 키를 사용하여 수행하는 방법을 묻지 만 UITextView를 사용할 때 키보드를 사라지게하려는 의도를 가진 사람에게 도움이 될 수 있다고 생각합니다.
private func addToolBarForTextView() {
let textViewToolbar: UIToolbar = UIToolbar()
textViewToolbar.barStyle = .default
textViewToolbar.items = [
UIBarButtonItem(title: "Cancel", style: .done,
target: self, action: #selector(cancelInput)),
UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
target: self, action: nil),
UIBarButtonItem(title: "Post Reply", style: .done,
target: self, action: #selector(doneInput))
]
textViewToolbar.sizeToFit()
yourTextView.inputAccessoryView = textViewToolbar
}
@objc func cancelInput() { print("cancel") }
@objc func doneInput() { print("done") }
override func viewDidLoad() {
super.viewDidLoad()
addToolBarForTextView()
}
viewDidLoad 또는 다른 라이프 사이클 메소드 에서 addToolBarForTextView () 를 호출 하십시오 .
그것은 나를위한 완벽한 솔루션 인 것 같습니다.
건배,
무라트
확인. 모두가 트릭으로 답변을 주었지만 이것을 달성하는 올바른 방법은
의 " 종료 종료시 종료 "이벤트에 다음 조치를 연결하십시오 Interface Builder
. ( TextField
' 종료시 종료했습니다 '에서 다음 cntrl-drag를 마우스 오른쪽 단추로 클릭하십시오 .
-(IBAction)hideTheKeyboard:(id)sender
{
[self.view endEditing:TRUE];
}
UITextViewDelegate
새로운 빠른 인터페이스를 사용하는 다른 답변과 비슷한 isNewline
것은 다음과 같습니다.
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if let character = text.first, character.isNewline {
textView.resignFirstResponder()
return false
}
return true
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if (range.length==0) {
if ([text isEqualToString:@"\n"]) {
[txtView resignFirstResponder];
if(textView.returnKeyType== UIReturnKeyGo){
[self PreviewLatter];
return NO;
}
return NO;
}
} return YES;
}
+ (void)addDoneButtonToControl:(id)txtFieldOrTextView
{
if([txtFieldOrTextView isKindOfClass:[UITextField class]])
{
txtFieldOrTextView = (UITextField *)txtFieldOrTextView;
}
else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
{
txtFieldOrTextView = (UITextView *)txtFieldOrTextView;
}
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,
0,
[Global returnDeviceWidth],
50)];
numberToolbar.barStyle = UIBarStyleDefault;
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"btn_return"]
style:UIBarButtonItemStyleBordered
target:txtFieldOrTextView
action:@selector(resignFirstResponder)];
numberToolbar.items = [NSArray arrayWithObjects:btnDone,nil];
[numberToolbar sizeToFit];
if([txtFieldOrTextView isKindOfClass:[UITextField class]])
{
((UITextField *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
}
else if([txtFieldOrTextView isKindOfClass:[UITextView class]])
{
((UITextView *)txtFieldOrTextView).inputAccessoryView = numberToolbar;
}
}
나는 이것이이 질문에 대한 정확한 대답이 아니라는 것을 알고 있지만 대답을 찾기 위해 인터넷을 사냥 한 후에이 스레드를 발견했습니다. 나는 다른 사람들이 그 느낌을 공유한다고 가정합니다.
이것은 신뢰할 수 있고 사용하기 쉬운 UITapGestureRecognizer의 변형입니다. TextView의 대리자를 ViewController로 설정하십시오.
TextView가 편집을 위해 활성화되면 ViewDidLoad 대신 UITapGestureRecognizer를 추가합니다.
-(void)textViewDidBeginEditing:(UITextView *)textView{
_tapRec = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
[self.view addGestureRecognizer: _tapRec];
NSLog(@"TextView Did begin");
}
TextView 외부를 탭하면 뷰가 편집 모드를 종료하고 UITapGestureRecognizer가 자동으로 제거되므로 뷰의 다른 컨트롤과 계속 상호 작용할 수 있습니다.
-(void)tap:(UITapGestureRecognizer *)tapRec{
[[self view] endEditing: YES];
[self.view removeGestureRecognizer:tapRec];
NSLog(@"Tap recognized, tapRec getting removed");
}
이게 도움이 되길 바란다. 너무 분명해 보이지만 웹 어디에서 나이 솔루션을 본 적이 없습니다.
Xcode 6.4.의 경우 Swift 1.2. :
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)
{
super.touchesBegan(touches, withEvent: event)
if let touch = touches.first as? UITouch
{
self.meaningTextview.resignFirstResponder()
}
}
UIToolbar
사용하기보다 쉽게 UITextView에 추가해야합니다.shouldChangeTextIn
스위프트 4에서
let toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
toolbar.barStyle = .default
toolbar.items = [
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil),
UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneAction))
]
textView.inputAccessoryView = toolbar
@objc func doneAction(){
self.textView.resignFirstResponder()
}
toolbar.sizeToFit()