3

I am working on custom keyboard. all works perfect but when i rotate the keyboard to landscape mode the keyboard load correctly but it takes the height of portrait mode keyboardview.

Landscape keyboard take wrong size

Here is my Try:

  @interface KeyboardViewController ()
{
CGFloat expandedHeight ;
BOOL isPortrait;
}
@property(strong,nonatomic)keyboardLayout *ObjKeyLayout;
 - (void)updateViewConstraints {
[super updateViewConstraints];
[self updateCustomHeight];
}
 -(void)updateCustomHeight
{


if (self.heightConstraint != nil) {
    [self.view removeConstraint:self.heightConstraint];
    [self.view layoutIfNeeded];
}
if(isPortrait)
{
    expandedHeight = 258;
}
else
{

    expandedHeight = 156;
}
self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.view      attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant: expandedHeight];
[self.view addConstraint:self.heightConstraint];
[self.view layoutIfNeeded];
}
- (void)deviceOrientationDidChange:(NSNotification *)notification
{
NSLog(@"key");
if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
    //Keyboard is in Portrait
    isPortrait=YES;
    isp=YES;
    [self LoadKeyboardview];
    [self updateCustomHeight];

}
else{

    isPortrait=NO;

    [self LoadKeyboardview];
    [self updateCustomHeight];

    //Keyboard is in Landscape
  }
  -(void)initiateOrientation
{
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
 if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
    //Keyboard is in Portrait
    isPortrait=YES;
    [self LoadKeyboardview];
}
else{
     isPortrait=NO;
    [self LoadKeyboardview];
  //Keyboard is in Landscape
}
 - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
    //Keyboard is in Portrait
    isPortrait=YES;
    [self LoadKeyboardview];
    [self updateCustomHeight];
    }
else{
     isPortrait=NO;
    [self LoadKeyboardview];
    [self updateCustomHeight];
     //Keyboard is in Landscape
 }
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
    //Keyboard is in Portrait
    isPortrait=YES;
     [self LoadKeyboardview];
    [self updateCustomHeight];
    }
else{
    isPortrait=NO;
     [self LoadKeyboardview];
    [self updateCustomHeight];
    }
   }
  - (NSLayoutConstraint*)findViewHeightConstraint {
NSArray *constraints = self.view.superview.constraints;
for ( NSLayoutConstraint *constraint in constraints ) {
    if ( constraint.firstItem == self.view
        && constraint.firstAttribute == NSLayoutAttributeHeight )
        return constraint;
}
[self updateCustomHeight];
return nil;
 }
 - (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
// Update height when rotating
  [self updateCustomHeight];
   }

EDIT : Portrait Mode

enter image description here

EDIT:-

     @implementation KeyboardViewController
      - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
    // Perform custom initialization work here
    self.portraitHeight = 256;
    self.landscapeHeight = 162;
  }
  return self;
    }

 - (void)viewDidLoad {
   [super viewDidLoad];

    // [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];



[self copyDatabaseIfNeeded];

NumKey=[[NSArray alloc]initWithObjects:@"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"0", @"-", @"/", @":", @";", @"(", @")", @"$", @"&", @"@", @"\"", @".", @",", @"?", @"!",@"'",@"^", nil];

arrAlphabet=[[NSArray alloc]initWithObjects:@"q", @"w", @"e", @"r", @"t", @"y", @"u", @"i", @"o", @"p", @"a", @"s", @"d", @"f", @"g", @"h", @"j", @"k", @"l", @"z", @"x", @"c", @"v", @"b",@"n",@"m", nil];

arrKeyImages=[[NSArray alloc]initWithObjects:@"Q_key.png", @"W_key.png", @"E_key.png", @"R_key.png", @"T_key.png", @"Y_key.png", @"U_key.png", @"I_key.png", @"O_key.png", @"P_key.png", @"A_key.png", @"S_key.png", @"D_key.png", @"F_key.png", @"G_key.png", @"H_key.png", @"J_key.png", @"K_key.png", @"L_key.png", @"Z_key.png", @"X_key.png", @"C_key.png", @"V_key.png", @"B_key.png",@"N_key.png",@"M_key.png", nil];



keyIpad=[[NSArray alloc]initWithObjects:@"Q_Land_key.png", @"W_Land_key.png", @"E_Land_key.png", @"R_Land_key.png", @"T_Land_key.png", @"Y_Land_key.png", @"U_Land_key.png", @"I_Land_key.png", @"O_Land_key.png", @"P_Land_key.png", @"A_Land_key.png", @"S_Land_key.png", @"D_Land_key.png", @"F_Land_key.png", @"G_Land_key.png", @"H_Land_key.png", @"J_Land_key.png", @"K_Land_key.png", @"L_Land_key.png", @"Z_Land_key.png", @"X_Land_key.png", @"C_Land_key.png", @"V_Land_key.png", @"B_Land_key.png",@"N_Land_key.png",@"M_Land_key.png", nil];


  arrspecialImageKey=[[NSArray alloc]initWithObjects:@"1_key.png", @"2_key.png", @"3_key.png", @"4_key.png", @"5_key.png", @"6_key.png", @"7_key.png", @"8_key.png", @"9_key.png", @"0_key.png", @"desh_key.png", @"slash.png", @"shift_shemi.png", @"semi.png", @"left_brecket.png", @"right_breacket.png", @"doller_key.png", @"and_key.png", @"AtTherate.png", @"dobleComma.png", @"dot.png",@"singel_comma.png",@"question_mark.png", @"exemlaration.png", @"single_uppar_comma.png",@"upparArrow.png", nil];


  arrSpecialIpad=[[NSArray alloc]initWithObjects:@"1_Land_key.png", @"2_Land_key.png", @"3_Land_key.png", @"4_Land_key.png", @"5_Land_key.png", @"6_Land_key.png", @"7_Land_key.png", @"8_Land_key.png", @"9_Land_key.png", @"0_Land_key.png", @"Dash_Land_key.png", @"slash_Land_key.png", @"shif_semi_Land_key", @"semi_Land_key", @"left_brecket_Land_key.png", @"right_Land_key.png", @"doller_Land_key.png", @"and_Land_key.png", @"attherate_Land_key.png", @"dobblecomma_Land_key", @"dot_Land_key.png",@"comma.png",@"question.png", @"exemeleter.png", @"uppar_comma.png",@"upArrow.png", nil];

 self.nextKeyboardButton = [UIButton buttonWithType:UIButtonTypeSystem];

 [self.nextKeyboardButton setTitle:NSLocalizedString(@"Next Keyboard", @"Title for 'Next Keyboard' button") forState:UIControlStateNormal];
 [self.nextKeyboardButton sizeToFit];
 self.nextKeyboardButton.translatesAutoresizingMaskIntoConstraints = NO;

 [self.nextKeyboardButton addTarget:self action:@selector(advanceToNextInputMode) forControlEvents:UIControlEventTouchUpInside];

 [self.view addSubview:self.nextKeyboardButton];
 self.nextKeyboardButton.hidden=YES;

   NSLayoutConstraint *nextKeyboardButtonLeftSideConstraint = [NSLayoutConstraint constraintWithItem:self.nextKeyboardButton attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0];
   NSLayoutConstraint *nextKeyboardButtonBottomConstraint = [NSLayoutConstraint constraintWithItem:self.nextKeyboardButton attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];
   [self.view addConstraints:@[nextKeyboardButtonLeftSideConstraint, nextKeyboardButtonBottomConstraint]];


  self.heightConstraint = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:self.portraitHeight];


    // Perform custom UI setup here

    }
    - (void)deviceOrientationDidChange:(NSNotification *)notification
 {
self.heightConstraint.constant=expandedHeight;
   NSLog(@"key");
   if([UIScreen mainScreen].bounds.size.width < [UIScreen mainScreen].bounds.size.height){
    //Keyboard is in Portrait
    isPortrait=YES;
    isp=YES;
    [self LoadKeyboardview];
    [self updateCustomHeight];

}
else{

    isPortrait=NO;

    [self LoadKeyboardview];
    [self updateCustomHeight];
 }
  - (NSLayoutConstraint*)findViewHeightConstraint {
NSArray *constraints = self.view.superview.constraints;
for ( NSLayoutConstraint *constraint in constraints ) {
    if ( constraint.firstItem == self.view
        && constraint.firstAttribute == NSLayoutAttributeHeight )
        return constraint;
   }
 //  [self updateCustomHeight];
   return nil;
 }
Badal Shah
  • 7,541
  • 2
  • 30
  • 65
  • You would be better to not keep removing and adding the height constraint. Instead add it the first time and then after that simply change its value using: `self.heightConstraint.constant=expandedHeight`. You then need to mark the view as needing layout using `[self.view setNeedsLayout]`, then do `[self.view layoutIfNeeded]`. – Rory McKinnel Aug 07 '15 at 08:45
  • thanks for replay @RoryMcKinnel. can you explain it in detail. i am first time making customkeyboard ? – Badal Shah Aug 07 '15 at 09:03

2 Answers2

1

If you use "auto layout" in designing of keyboard in xib then there is no need to add height constraint,it automatically adjust according to default keyboard size.I simply load the view and not add any height constraint and i works fine for me in all devices.

 override func viewDidLoad() {
        super.viewDidLoad()
        let nib = UINib(nibName: "VSPKeyboardViewController", bundle: nil)
        let objects = nib.instantiateWithOwner(self, options: nil)
        view = objects[0] as! UIView

}

override func updateViewConstraints() {
        super.updateViewConstraints()
}
VSP
  • 166
  • 11
  • pated :- i have done as you said but if i remove the programatically constrain then my keyboard wil be cutted in portrait mode . – Badal Shah Aug 07 '15 at 12:57
  • @BadalShah Could you please share your code (viewdidload method),that how you load the nib in your class because i only load the nib and not doing any other code for layout and my keyboard work fine in all devices – VSP Aug 07 '15 at 13:27
0

You would be better to not keep removing and adding the height constraint. Instead add it the first time and then after that simply change its value and set the view as needing layout and then do the layout.

Also think your might be working out the orientation wrong by using bounds before the transition occurs.

Updated your methods as follows:

- (void)viewWillTransitionToSize:(CGSize)size 
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator{
  if (size.width < size.height){
    //Keyboard is in Portrait
    isPortrait=YES;
    [self LoadKeyboardview];
    [self updateCustomHeight];
  }
  else{
    // New orientation is landscape
    isPortrait=NO;
    [self LoadKeyboardview];
    [self updateCustomHeight];
 }
}


-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
                               duration:(NSTimeInterval)duration{
  if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
      toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
    //Keyboard will be Portrait
    isPortrait=YES;
    [self LoadKeyboardview];
    [self updateCustomHeight];
  }
  else{
    //Keyboard will be Landscape
    isPortrait=NO;
     [self LoadKeyboardview];
    [self updateCustomHeight];
  }
}

-(void)updateCustomHeight
{
  if(isPortrait){
    expandedHeight = 258;
  }
  else{
    expandedHeight = 156;
  }

  // If no constraint add one, or if one exists update it only
  // if the height needs to change.
  if (self.heightConstraint == nil) {
    self.heightConstraint = 
      [NSLayoutConstraint constraintWithItem:self.view      
                                   attribute:NSLayoutAttributeHeight 
                                   relatedBy:NSLayoutRelationEqual toItem:nil 
                                   attribute:NSLayoutAttributeNotAnAttribute 
                                  multiplier:0.0 
                                    constant:expandedHeight];
    [self.view addConstraint:self.heightConstraint];
    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
  }
  else if (self.heightConstraint.constant != expandedHeight){
    self.heightConstraint.constant = expandedHeight;
    [self.view setNeedsLayout];
    [self.view layoutIfNeeded];
  }
}
Rory McKinnel
  • 7,936
  • 2
  • 17
  • 28
  • i wrote as you said but then i get less size in my portrait keyboard where as i need more size for portrait keyboard . please check edited question. – Badal Shah Aug 07 '15 at 09:28
  • I think you have an issue with the calculation of isPortrait. In your code use the size passed to work out orientation and not the screen bounds which may not change until after the transition has occurred. – Rory McKinnel Aug 07 '15 at 09:37
  • I have used different .XIB for portrait (Left and right side keyboard) and Landscape mode keyboard. total 3 .XIBs i used. – Badal Shah Aug 07 '15 at 09:38
  • Updated with revised orientation methods to work out orientation. I think your original ones relying on the screen bounds was possibly wrong. The iOS8 version tells you the new `size` so code uses that. The iOS7 version tells you the new orientation, so new code uses that instead. Can you show your code for `LoadKeyboardview`? Sounds like you are replacing the keyboard from what you just said as well when orientation changes? Code should still be ok as long as self.view is not changed as that is where the constraint is being applied. – Rory McKinnel Aug 07 '15 at 09:49
  • Still getting same result. Portrait keyboard size not increased. – Badal Shah Aug 07 '15 at 10:00
  • Is it the wrong height at startup in Portrait, or also when you rotate horizontal then rotate back? Do the heights change at all? If only at startup on Portrait it could be because `isPortrait` is not initilized as YES. – Rory McKinnel Aug 07 '15 at 11:27
  • portrait mode and landscape mode got same size on keyboard view. if i change the size of portrait mode then landscape keyboardsize also changed . – Badal Shah Aug 07 '15 at 13:21
  • @BadalShah I would put break points at the lines where the constraint constant is set or where the constraint is added and set and look at the values being set to see if the right heights are being used. Then you know if that code is working or not. Please say if it is or not. If not then that is your issue, otherwise good news is that code seems right and something else is preventing the resizing. Check the debug console for unsatisfied constraint errors. It could be you have another constraint which is clashing. – Rory McKinnel Aug 07 '15 at 13:39
  • @BadalShah How did you get on with your problem? – Rory McKinnel Aug 11 '15 at 10:02
  • thanks for the help. i have set constrain for expand height in `viewdidappear` method. – Badal Shah Aug 11 '15 at 10:11