简体   繁体   English

iOS 7-SplitViewController详细视图-自动布局UITextView键盘方向更改

[英]iOS 7 - SplitViewController Detail View - Autolayout UITextView Keyboard Orientation Change

I can't believe I've been stuck on this for over a week. 我不敢相信我已经坚持了一个多星期。

I've seen (and tried) every other Stack question / answer on this I could find and none work. 我已经看到(并尝试过)我能找到的所有其他Stack问题/答案,但均无效果。

Basically I have a detail view with a toolbar and underneath a UITextView that takes up the rest of the space leaving a 20 point border around it's edges to the edge of the superview. 基本上,我有一个带工具栏的详细视图,在一个UITextView之下,该UITextView占据了其余的空间,在其边缘到Superview的边缘之间留有20点的边界。

All I need is when the keyboard is displayed the textview will either change it's frame or it's content inset stuff, so that the keyboard doesn't cover anything up and the text scrolls to the end of it's text, and any new typing / line wrapping is not hidden by the keyboard - simple right? 我需要的是,当显示键盘时,textview会更改其框架或其内容插入内容,以使键盘不会覆盖任何内容,并且文本会滚动到其文本的末尾,并且会进行任何新的键入/换行不是被键盘隐藏的-简单吧? Er... no. 呃没有。

If the user changes Orientation (all 4 supported) then it needs to adjust to accommodate. 如果用户更改了Orientation (全部支持4个),则需要进行调整以适应。

Then with keyboard dismissal it needs to return to it's full size ( depending on possible new orientation ). 然后,在关闭键盘的情况下,需要恢复到其完整大小(取决于可能的新方向)。

This is the first project I've done with both Autolayout and iOS 7 (and I've run into the bug in iOS7 that puts your new line of text 'below' the bottom of the text view, but thanks to a stack fix that's okay now.) 这是我同时使用AutolayoutiOS 7进行的第一个项目(并且我遇到了iOS7中的错误,该错误将您的新文本行置于文本视图的底部下方,但是由于有了堆栈修复程序,好吧。)

However NONE of the solutions I've tried from this site work. 但是,我在此站点上尝试过的所有解决方案都没有。

I'm setting the constraints for the UITextView by positioning it in IB in portrait and selecting 'reset to suggested constraints' - that seems to lay it out correctly for all 4 orientations if the keyboard is not displayed. 我通过将UITextView的约束放置在portrait IB中并选择“重置为建议的约束”来设置UITextView的约束-如果未显示键盘,这似乎可以针对所有4个方向正确地布置它。

It can be done by adjusting the constraint to the bottom of the view when the keyboard appears and disappears. 可以通过在键盘出现和消失时将约束调整到视图底部来完成。 In the example below, I have a view controller with a tool bar and a text view. 在下面的示例中,我有一个带有工具栏和文本视图的视图控制器。 The text view has constraints (with a value of 20) to the bottom and sides of the main view, and one to the tool bar at the top of the view. 文本视图对主视图的底部和侧面具有约束(值为20),对视图顶部的工具栏具有约束。 I have an IBOutlet to the constraint to the bottom of the view. 我对视图底部的约束有一个IBOutlet。 Notice that in the keyboardWillShow: method, I have to check on the orientation of the view in order to get the constraint's constant value correct -- in landscape mode, the keyboard's width and height are reversed (that is, what you get as size.width is actually the height, and size.height gives you the width). 请注意,在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];
}

The suggested code fix above from the incredibly helpful rdelmar works perfectly in portrait. 以上来自极有帮助的rdelmar的建议代码修复可以完美地纵向运行。 Changing to landscape however produces this crash: 但是更改为横向会导致此崩溃:

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.

Now, I've cleared EVERY constraint from my detail view, and started over. 现在,我从详细视图中清除了每个约束,然后重新开始。 The UILabel, UIToolBar and UITextView have all had their leading, trailing and top edges PINNED. UILabel,UIToolBar和UITextView都有其前缘,后缘和顶端边缘。

The UITextView also had it's BOTTOM EDGE PINNED. UITextView还具有底部边缘固定。

And this bottom constraint is the one linked to the IBOutlet mentioned in the above post. 这个底部约束是与以上文章中提到的IBOutlet链接的约束。

Any more ideas what's going wrong? 还有其他想法出什么事了吗?

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

if ( kbSize.height < kbSize.width )

This was the only change required to the answer above by rdelmar. 这是rdelmar对上述答案所做的唯一更改。 Thanks so much! 非常感谢! This drove me mad for a week!!!! 这使我发疯了一个星期!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Swift 中以编程方式更改 splitViewController 中的详细视图 - How to change detail View in splitViewController programatically in Swift 使用AutoLayout更改方向时更改UITextView高度 - Changing UITextView height on orientation change with AutoLayout iOS-自动版式-在方向更改时按比例增加/减小视图大小 - iOS - Autolayout - Increase/Decrease view size proportionally on orientation change 在iOS中使用自动布局更改设备旋转的视图方向 - Change orientation of view on device rotation using Autolayout in iOS iOS SplitViewController详细视图的数据为空/未加载,但视图为 - IOS SplitViewController detail view's data is empty / not loading, but the view is iOS 8中UITextView的自定义键盘因方向错误而崩溃 - Custom keyboard for UITextView in iOS 8 crashes with orientation error iOS自动版式-方向更改会丢失约束修改? - iOS Autolayout - constraints modifications lost on orientation change? UIScrollView中UITextView中的键盘方向 - Keyboard orientation in UITextView in UIScrollView 在自定义SplitViewController中处理方向更改? - Handling orientation change in custom SplitViewController? iOS视图不会在方向更改时更改方向 - iOS View does not change orientation on orientation change
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM