diff --git a/Signal/src/UIView+OWS.h b/Signal/src/UIView+OWS.h index a9230dfa3..74df2270b 100644 --- a/Signal/src/UIView+OWS.h +++ b/Signal/src/UIView+OWS.h @@ -60,6 +60,27 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value); - (void)centerOnSuperview; +#pragma mark - RTL + +// For correct right-to-left layout behavior, use "leading" and "trailing", +// not "left" and "right". +// +// NOTE: the margin values are inverted in RTL layouts. +- (BOOL)isRTL; +- (void)autoPinLeadingAndTrailingToSuperview; +- (void)autoPinLeadingToSuperView; +- (void)autoPinLeadingToSuperViewWithMargin:(CGFloat)margin; +- (void)autoPinTrailingToSuperView; +- (void)autoPinTrailingToSuperViewWithMargin:(CGFloat)margin; +- (void)autoPinLeadingToTrailingOfView:(UIView *)view; +- (void)autoPinLeadingToTrailingOfView:(UIView *)view margin:(CGFloat)margin; +- (void)autoPinLeadingToView:(UIView *)view; +- (void)autoPinLeadingToView:(UIView *)view margin:(CGFloat)margin; +- (void)autoPinTrailingToView:(UIView *)view; +- (void)autoPinTrailingToView:(UIView *)view margin:(CGFloat)margin; +// Return Right on LTR and Right on RTL. +- (NSTextAlignment)textAlignmentUnnatural; + #pragma mark - Debugging - (void)addBorderWithColor:(UIColor *)color; diff --git a/Signal/src/UIView+OWS.m b/Signal/src/UIView+OWS.m index f0379e3b5..59b081e01 100644 --- a/Signal/src/UIView+OWS.m +++ b/Signal/src/UIView+OWS.m @@ -35,6 +35,7 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value) { [self autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:self.superview withOffset:+margin]; [self autoPinEdge:ALEdgeRight toEdge:ALEdgeRight ofView:self.superview withOffset:-margin]; + // TODO: } - (void)autoPinWidthToSuperview @@ -43,6 +44,12 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value) [self autoPinEdge:ALEdgeRight toEdge:ALEdgeRight ofView:self.superview]; } +- (void)autoPinLeadingAndTrailingToSuperview +{ + [self autoPinLeadingToSuperView]; + [self autoPinTrailingToSuperView]; +} + - (void)autoPinHeightToSuperviewWithMargin:(CGFloat)margin { [self autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:self.superview withOffset:+margin]; @@ -204,6 +211,93 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value) self.height); } +#pragma mark - RTL + +- (BOOL)isRTL +{ + return ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.semanticContentAttribute] + == UIUserInterfaceLayoutDirectionRightToLeft); +} + +- (CGFloat)rtlSafeConstant:(CGFloat)value +{ + return (self.isRTL ? -value : value); +} + +- (void)autoPinLeadingToSuperView +{ + [self autoPinLeadingToSuperViewWithMargin:0]; +} + +- (void)autoPinLeadingToSuperViewWithMargin:(CGFloat)margin +{ + [self.leadingAnchor constraintEqualToAnchor:self.superview.layoutMarginsGuide.leadingAnchor + constant:[self rtlSafeConstant:margin]] + .active + = YES; +} + +- (void)autoPinTrailingToSuperView +{ + [self autoPinTrailingToSuperViewWithMargin:0]; +} + +- (void)autoPinTrailingToSuperViewWithMargin:(CGFloat)margin +{ + [self.trailingAnchor constraintEqualToAnchor:self.superview.layoutMarginsGuide.trailingAnchor + constant:[self rtlSafeConstant:margin]] + .active + = YES; +} + +- (void)autoPinLeadingToTrailingOfView:(UIView *)view +{ + OWSAssert(view); + + [self autoPinLeadingToTrailingOfView:view margin:0]; +} + +- (void)autoPinLeadingToTrailingOfView:(UIView *)view margin:(CGFloat)margin +{ + OWSAssert(view); + + [self.leadingAnchor constraintEqualToAnchor:view.trailingAnchor constant:margin].active = YES; +} + +- (void)autoPinLeadingToView:(UIView *)view +{ + OWSAssert(view); + + [self autoPinLeadingToView:view margin:0]; +} + +- (void)autoPinLeadingToView:(UIView *)view margin:(CGFloat)margin +{ + OWSAssert(view); + + [self.leadingAnchor constraintEqualToAnchor:view.leadingAnchor constant:[self rtlSafeConstant:margin]].active = YES; +} + +- (void)autoPinTrailingToView:(UIView *)view +{ + OWSAssert(view); + + [self autoPinTrailingToView:view margin:0]; +} + +- (void)autoPinTrailingToView:(UIView *)view margin:(CGFloat)margin +{ + OWSAssert(view); + + [self.trailingAnchor constraintEqualToAnchor:view.trailingAnchor constant:[self rtlSafeConstant:margin]].active + = YES; +} + +- (NSTextAlignment)textAlignmentUnnatural +{ + return (self.isRTL ? NSTextAlignmentLeft : NSTextAlignmentRight); +} + #pragma mark - Debugging - (void)addBorderWithColor:(UIColor *)color diff --git a/Signal/src/ViewControllers/SelectRecipientViewController.m b/Signal/src/ViewControllers/SelectRecipientViewController.m index c38a7f259..0aab840a4 100644 --- a/Signal/src/ViewControllers/SelectRecipientViewController.m +++ b/Signal/src/ViewControllers/SelectRecipientViewController.m @@ -158,7 +158,7 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien if (!_phoneNumberTextField) { _phoneNumberTextField = [UITextField new]; _phoneNumberTextField.font = [UIFont ows_mediumFontWithSize:18.f]; - _phoneNumberTextField.textAlignment = NSTextAlignmentRight; + _phoneNumberTextField.textAlignment = _phoneNumberTextField.textAlignmentUnnatural; _phoneNumberTextField.textColor = [UIColor ows_materialBlueColor]; _phoneNumberTextField.placeholder = NSLocalizedString( @"REGISTRATION_ENTERNUMBER_DEFAULT_TEXT", @"Placeholder text for the phone number textfield"); @@ -200,13 +200,14 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien { UIView *row = [UIView new]; [superview addSubview:row]; - [row autoPinWidthToSuperview]; + [row autoPinLeadingAndTrailingToSuperview]; if (previousRow) { [row autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:previousRow withOffset:0]; } else { [row autoPinEdgeToSuperviewEdge:ALEdgeTop]; } [row autoSetDimension:ALDimensionHeight toSize:height]; + row.layoutMargins = UIEdgeInsetsMake(0, 0, 0, 0); return row; } @@ -455,6 +456,8 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien OWSAssert(strongSelf); UITableViewCell *cell = [UITableViewCell new]; + cell.preservesSuperviewLayoutMargins = YES; + cell.contentView.preservesSuperviewLayoutMargins = YES; // Country Row UIView *countryRow = [self createRowWithHeight:kCountryRowHeight previousRow:nil superview:cell.contentView]; @@ -463,11 +466,11 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien UILabel *countryCodeLabel = self.countryCodeLabel; [countryRow addSubview:countryCodeLabel]; - [countryCodeLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:20.f]; + [countryCodeLabel autoPinLeadingToSuperView]; [countryCodeLabel autoVCenterInSuperview]; [countryRow addSubview:self.countryCodeButton]; - [self.countryCodeButton autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:20.f]; + [self.countryCodeButton autoPinTrailingToSuperView]; [self.countryCodeButton autoVCenterInSuperview]; // Phone Number Row @@ -479,12 +482,12 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien UILabel *phoneNumberLabel = self.phoneNumberLabel; [phoneNumberRow addSubview:phoneNumberLabel]; - [phoneNumberLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:20.f]; + [phoneNumberLabel autoPinLeadingToSuperView]; [phoneNumberLabel autoVCenterInSuperview]; [phoneNumberRow addSubview:self.phoneNumberTextField]; - [self.phoneNumberTextField autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:20.f]; - [self.phoneNumberTextField autoPinEdge:ALEdgeLeft toEdge:ALEdgeRight ofView:phoneNumberLabel withOffset:0]; + [self.phoneNumberTextField autoPinLeadingToTrailingOfView:phoneNumberLabel margin:10.f]; + [self.phoneNumberTextField autoPinTrailingToSuperView]; [self.phoneNumberTextField autoVCenterInSuperview]; // Example row. @@ -493,14 +496,14 @@ NSString *const kSelectRecipientViewControllerCellIdentifier = @"kSelectRecipien superview:cell.contentView]; [examplePhoneNumberRow addSubview:self.examplePhoneNumberLabel]; [self.examplePhoneNumberLabel autoVCenterInSuperview]; - [self.examplePhoneNumberLabel autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:20.f]; + [self.examplePhoneNumberLabel autoPinTrailingToSuperView]; // Phone Number Button Row UIView *buttonRow = [self createRowWithHeight:kButtonRowHeight previousRow:examplePhoneNumberRow superview:cell.contentView]; [buttonRow addSubview:self.phoneNumberButton]; [self.phoneNumberButton autoVCenterInSuperview]; - [self.phoneNumberButton autoPinEdgeToSuperviewEdge:ALEdgeRight withInset:20.f]; + [self.phoneNumberButton autoPinTrailingToSuperView]; [buttonRow autoPinEdgeToSuperviewEdge:ALEdgeBottom]; diff --git a/Signal/src/views/ContactTableViewCell.m b/Signal/src/views/ContactTableViewCell.m index de7b099ff..b50c3945e 100644 --- a/Signal/src/views/ContactTableViewCell.m +++ b/Signal/src/views/ContactTableViewCell.m @@ -66,14 +66,14 @@ const NSUInteger kContactTableViewCellAvatarSize = 40; [self.contentView addSubview:_nameLabel]; [_avatarView autoVCenterInSuperview]; - [_avatarView.leadingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.leadingAnchor].active = YES; + [_avatarView autoPinLeadingToSuperView]; [_avatarView autoSetDimension:ALDimensionWidth toSize:kContactTableViewCellAvatarSize]; [_avatarView autoSetDimension:ALDimensionHeight toSize:kContactTableViewCellAvatarSize]; [_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeTop]; [_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom]; - [_nameLabel.leadingAnchor constraintEqualToAnchor:_avatarView.trailingAnchor constant:12.f].active = YES; - [_nameLabel.trailingAnchor constraintEqualToAnchor:self.contentView.layoutMarginsGuide.trailingAnchor].active = YES; + [_nameLabel autoPinLeadingToTrailingOfView:_avatarView margin:12.f]; + [_nameLabel autoPinTrailingToSuperView]; // Force layout, since imageView isn't being initally rendered on App Store optimized build. [self layoutSubviews];