2013-11-01 58 views
0

我不敢相信我一直堅持這一個多星期。iOS 7 - SplitViewController細節視圖 - Autolayout UITextView鍵盤方向更改

我已經看到(並嘗試過)每個其他Stack問題/答案,我可以找到,沒有工作。

基本上我有一個工具欄和一個UITextView下的詳細視圖,佔用剩餘的空間,在它的邊緣附近留下一個20點的邊界到超視圖的邊緣。

我只需要顯示鍵盤時,textview將改變其框架或其內容插入的東西,以便鍵盤不會覆蓋任何東西,文本滾動到文本的末尾,並且任何新的打字/換行不會被鍵盤隱藏 - 簡單的權利?呃沒有。

如果用戶更改Orientation(全部支持4),則需要調整以適應。

然後在鍵盤解除的情況下,它需要返回到它的全尺寸(取決於可能的新方向)。

這是第一個項目,我既AutolayoutiOS 7做(我已經運行到iOS7是把你的新的「自下而上」的文本視圖的底部文本行的bug,但由於採用了現在沒關係修復。)

但是我從這個網站上試過的解決方案都沒有。

我將UITextView的約束條件設置在portrait的IB中,然後選擇'重置爲建議的約束' - 如果沒有顯示鍵盤,則對於所有4個方向似乎都正確佈置約束。

回答

1

當鍵盤出現並消失時,可以通過調整視圖底部的約束來完成。在下面的例子中,我有一個帶有工具欄和文本視圖的視圖控制器。文本視圖對主視圖的底部和側面有約束(值爲20),對視圖頂部的工具欄有一個約束。我有一個IBOutlet來限制視圖的底部。請注意,在keyboardWillShow:方法中,我必須檢查視圖的方向,以便獲得約束的常量值 - 在橫向模式下,鍵盤的寬度和高度是相反的(即,您得到的尺寸。寬度實際上是高度,size.height給你的寬度)。

@interface ViewController() 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bottomCon; // outlet to the constraint between the text view and the bottom of the view 
@property (weak,nonatomic) IBOutlet UITextView *tv; // outlet for the text view 
@end 

@implementation ViewController 


- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; 
} 



- (void)keyboardWillShow:(NSNotification*)aNotification { 
    NSDictionary* info = [aNotification userInfo]; 
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 
    if (self.view.bounds.size.width < self.view.bounds.size.height) { 
     self.bottomCon.constant = kbSize.height + 20; 
    }else{ 
     self.bottomCon.constant = kbSize.width + 20; 
    } 
} 


-(void)keyboardDidShow:(NSNotification *) aNotificaation { 
    [self.tv scrollRangeToVisible:NSMakeRange(self.tv.text.length - 1, 1)]; 
} 


- (void)keyboardWillHide:(NSNotification*)aNotification { 
    self.bottomCon.constant = 20; 
} 

-(IBAction)finishedEditing:(id)sender { // action for "Done" button on tool bar 
    [self.tv resignFirstResponder]; 
} 
+0

非常感謝您花時間編寫代碼。 它幾乎可以工作..在肖像 - 這很好。如果我然後轉到景觀 - 我得到一個例外 - 我試圖在這裏張貼它,但'評論部分太嚴格了(並處理新行回報很糟糕) – iOSProgrammingIsFun

+0

我已經添加了一個新的'答案'顯示崩潰..這是否有助於找出我要出錯的地方? 這爲什麼這麼複雜?誰在蘋果認爲這個實施是正確的想法? – iOSProgrammingIsFun

+0

@iOSProgrammingIsFun,在得到鍵盤大小之前我發現高度和寬度被顛倒了之前,我得到了那個錯誤 - 你的代碼和我的代碼完全一樣,因爲我已經在肖像和風景中測試過我的代碼,它工作正常。嘗試在keyboardWillShow方法中記錄鍵盤的大小,並查看它在縱向和橫向上的效果。 – rdelmar

0

建議的代碼修復上面的令人難以置信的有用rdelmar完美的肖像。更改爲景觀但是產生這種崩潰:

Unable to simultaneously satisfy constraints. 
    Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x941da50 V:|-(158)-[UITextView:0x9926000] (Names: '|':UIView:0x9449a30)>", 
    "<NSLayoutConstraint:0x9449a00 V:[UITextView:0x9926000]-(1044)-| (Names: '|':UIView:0x9449a30)>", 
    "<NSAutoresizingMaskLayoutConstraint:0x97b2d70 h=--& v=--& V:[UIView:0x9449a30(768)]>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x9449a00 V:[UITextView:0x9926000]-(1044)-| (Names: '|':UIView:0x9449a30)> 

Break on objc_exception_throw to catch this in the debugger. 
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

現在,我已經清除從我的詳細視圖中的每個約束,並開始了。 UILabel,UIToolBar和UITextView都有它們的前導,尾部和頂部邊緣PINNED。

該UITextView也有它的底部邊緣PINNED。

而這個底部約束是與上述帖子中提到的IBOutlet鏈接的。

還有什麼想法發生了什麼問題?

0
CGSize kbSize  = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 

if (kbSize.height < kbSize.width) 

這是rdelmar上述答案所需的唯一更改。非常感謝!這讓我生氣了一週!