diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h index 0882a50f2..17e2d20a5 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.h @@ -13,7 +13,8 @@ extern const CGFloat kBubbleHRounding; extern const CGFloat kBubbleThornSideInset; extern const CGFloat kBubbleThornVInset; extern const CGFloat kBubbleTextHInset; -extern const CGFloat kBubbleTextVInset; +extern const CGFloat kBubbleTextTopInset; +extern const CGFloat kBubbleTextBottomInset; @class OWSBubbleView; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m index b14f604a3..88e49856d 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSBubbleView.m @@ -7,14 +7,15 @@ NS_ASSUME_NONNULL_BEGIN -const CGFloat kOWSMessageCellCornerRadius = 17; +const CGFloat kOWSMessageCellCornerRadius = 18; const CGFloat kBubbleVRounding = kOWSMessageCellCornerRadius; const CGFloat kBubbleHRounding = kOWSMessageCellCornerRadius; const CGFloat kBubbleThornSideInset = 5.f; const CGFloat kBubbleThornVInset = 0; const CGFloat kBubbleTextHInset = 10.f; -const CGFloat kBubbleTextVInset = 10.f; +const CGFloat kBubbleTextTopInset = 8.f; +const CGFloat kBubbleTextBottomInset = 6.f; @interface OWSBubbleView () diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactOffersCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactOffersCell.m index 253c39bf1..a86655a7b 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactOffersCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactOffersCell.m @@ -100,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)titleFont { - return UIFont.ows_dynamicTypeBodyFont.ows_medium; + return UIFont.ows_dynamicTypeBodyFont.ows_mediumWeight; } - (UIFont *)buttonFont diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index 0a678bf2e..f581c2ab4 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -1003,12 +1003,12 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)textTopMargin { - return kBubbleTextVInset; + return kBubbleTextTopInset; } - (CGFloat)textBottomMargin { - return kBubbleTextVInset + kBubbleThornVInset; + return kBubbleTextBottomInset + kBubbleThornVInset; } - (UIColor *)bodyTextColor diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index cd4171307..3825b413a 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN [self.contentView addSubview:self.dateHeaderLabel]; self.footerLabel = [UILabel new]; - self.footerLabel.font = UIFont.ows_dynamicTypeCaption1Font; + self.footerLabel.font = UIFont.ows_dynamicTypeCaption2Font; self.footerLabel.textColor = [UIColor lightGrayColor]; [self.footerView addSubview:self.footerLabel]; @@ -80,7 +80,6 @@ NS_ASSUME_NONNULL_BEGIN [self.messageBubbleView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.dateHeaderLabel]; [self.footerView autoPinEdgeToSuperviewEdge:ALEdgeBottom]; - [self.footerView autoPinWidthToSuperview]; self.contentView.userInteractionEnabled = YES; @@ -161,6 +160,10 @@ NS_ASSUME_NONNULL_BEGIN [self.messageBubbleView configureViews]; [self.messageBubbleView loadContent]; + // Update label fonts to honor dynamic type size. + self.dateHeaderLabel.font = self.dateHeaderDateFont; + self.footerLabel.font = UIFont.ows_dynamicTypeCaption2Font; + if (self.shouldHaveFailedSendBadge) { self.failedSendBadgeView = [UIImageView new]; self.failedSendBadgeView.image = @@ -294,7 +297,7 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)footerVSpacing { - return 1.f; + return 0.f; } - (void)updateFooter @@ -327,6 +330,13 @@ NS_ASSUME_NONNULL_BEGIN return; } + [self.viewConstraints addObjectsFromArray:@[ + (self.isIncoming ? [self.footerView autoPinLeadingToSuperviewMarginWithInset:kBubbleThornSideInset] + : [self.footerView autoPinTrailingToSuperviewMarginWithInset:kBubbleThornSideInset]), + (self.isIncoming ? [self.footerView autoPinTrailingToSuperviewMargin] + : [self.footerView autoPinLeadingToSuperviewMargin]), + ]]; + [self.viewConstraints addObject:[self.footerView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.messageBubbleView @@ -376,7 +386,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)dateHeaderDateFont { - return UIFont.ows_dynamicTypeCaption1Font.ows_medium; + return UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight; } - (UIFont *)dateHeaderTimeFont diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m index b9dc4aeb9..a2e84cacb 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m @@ -412,7 +412,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)quotedAuthorFont { - return UIFont.ows_dynamicTypeCaption1Font.ows_medium; + return UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight; } - (UIColor *)quotedAuthorColor @@ -467,7 +467,7 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)quotedTextBottomInset { - return 4.f; + return 8.f; } - (CGFloat)quotedReplyStripeThickness diff --git a/Signal/src/ViewControllers/HomeView/HomeViewCell.m b/Signal/src/ViewControllers/HomeView/HomeViewCell.m index 371e6393b..4109d65eb 100644 --- a/Signal/src/ViewControllers/HomeView/HomeViewCell.m +++ b/Signal/src/ViewControllers/HomeView/HomeViewCell.m @@ -24,6 +24,10 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) UILabel *nameLabel; @property (nonatomic) UILabel *snippetLabel; @property (nonatomic) UILabel *dateTimeLabel; +// The unread badge has a larger v-height than the other elements in its +// row. We don't want it to distort the v-alignment of the cell's labels +// so we use a container to reserve the correct width. +@property (nonatomic) UIView *unreadBadgeContainer; @property (nonatomic) UIView *unreadBadge; @property (nonatomic) UILabel *unreadLabel; @@ -121,8 +125,14 @@ NS_ASSUME_NONNULL_BEGIN self.unreadLabel.lineBreakMode = NSLineBreakByTruncatingTail; self.unreadLabel.textAlignment = NSTextAlignmentCenter; + self.unreadBadgeContainer = [UIView containerView]; + [self.unreadBadgeContainer setContentHuggingHigh]; + [self.unreadBadgeContainer setCompressionResistanceHigh]; + self.unreadBadge = [NeverClearView new]; self.unreadBadge.backgroundColor = [UIColor ows_materialBlueColor]; + [self.unreadBadgeContainer addSubview:self.unreadBadge]; + [self.unreadBadge autoCenterInSuperview]; [self.unreadBadge setContentHuggingHigh]; [self.unreadBadge setCompressionResistanceHigh]; @@ -181,7 +191,7 @@ NS_ASSUME_NONNULL_BEGIN NSUInteger unreadCount = [[OWSMessageUtils sharedManager] unreadMessagesInThread:thread]; if (unreadCount > 0) { - [self.topRowView addArrangedSubview:self.unreadBadge]; + [self.topRowView addArrangedSubview:self.unreadBadgeContainer]; self.unreadLabel.font = [UIFont ows_dynamicTypeCaption1Font]; self.unreadLabel.text = [OWSFormat formatInt:MIN(99, (int)unreadCount)]; @@ -193,6 +203,7 @@ NS_ASSUME_NONNULL_BEGIN self.unreadBadge.layer.cornerRadius = unreadBadgeSize / 2; [self.viewConstraints addObjectsFromArray:@[ + [self.unreadBadgeContainer autoSetDimension:ALDimensionWidth toSize:unreadBadgeSize], [self.unreadBadge autoSetDimension:ALDimensionWidth toSize:unreadBadgeSize], [self.unreadBadge autoSetDimension:ALDimensionHeight toSize:unreadBadgeSize], ]]; @@ -239,7 +250,7 @@ NS_ASSUME_NONNULL_BEGIN initWithString:NSLocalizedString(@"HOME_VIEW_BLOCKED_CONTACT_CONVERSATION", @"A label for conversations with blocked users.") attributes:@{ - NSFontAttributeName : self.snippetFont.ows_medium, + NSFontAttributeName : self.snippetFont.ows_mediumWeight, NSForegroundColorAttributeName : [UIColor ows_blackColor], }]]; } else { @@ -259,7 +270,7 @@ NS_ASSUME_NONNULL_BEGIN initWithString:displayableText attributes:@{ NSFontAttributeName : - (hasUnreadMessages ? self.snippetFont.ows_medium + (hasUnreadMessages ? self.snippetFont.ows_mediumWeight : self.snippetFont), NSForegroundColorAttributeName : (hasUnreadMessages ? [UIColor ows_blackColor] @@ -291,9 +302,9 @@ NS_ASSUME_NONNULL_BEGIN dateTimeString = [[DateUtil timeFormatter] stringFromDate:date]; } - return [[NSAttributedString alloc] initWithString:dateTimeString + return [[NSAttributedString alloc] initWithString:dateTimeString.uppercaseString attributes:@{ - NSForegroundColorAttributeName : [UIColor ows_darkGrayColor], + NSForegroundColorAttributeName : [UIColor blackColor], NSFontAttributeName : self.dateTimeFont, }]; } @@ -302,7 +313,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)dateTimeFont { - return [UIFont ows_dynamicTypeFootnoteFont]; + return [UIFont ows_dynamicTypeFootnoteFont].ows_mediumWeight; } - (UIFont *)snippetFont @@ -312,7 +323,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)nameFont { - return [UIFont ows_dynamicTypeBodyFont].ows_medium; + return [UIFont ows_dynamicTypeBodyFont].ows_mediumWeight; } // Used for profile names. @@ -339,7 +350,17 @@ NS_ASSUME_NONNULL_BEGIN + (CGFloat)rowHeight { - return 72; + // Scale the cell height using size of dynamic "body" type as a reference. + const CGFloat kReferenceFontSizeMin = 17.f; + const CGFloat kReferenceFontSizeMax = 23.f; + CGFloat referenceFontSize = UIFont.ows_dynamicTypeBodyFont.pointSize; + CGFloat alpha = CGFloatClamp01(CGFloatInverseLerp(referenceFontSize, kReferenceFontSizeMin, kReferenceFontSizeMax)); + + const CGFloat kCellHeightMin = 68.f; + const CGFloat kCellHeightMax = 76.f; + CGFloat result = ceil(CGFloatLerp(kCellHeightMin, kCellHeightMax, alpha)); + + return result; } - (NSUInteger)cellHMargin @@ -369,7 +390,7 @@ NS_ASSUME_NONNULL_BEGIN self.thread = nil; self.contactsManager = nil; - [self.unreadBadge removeFromSuperview]; + [self.unreadBadgeContainer removeFromSuperview]; [[NSNotificationCenter defaultCenter] removeObserver:self]; } diff --git a/SignalMessaging/categories/UIFont+OWS.h b/SignalMessaging/categories/UIFont+OWS.h index af28e1cd9..9d73f4453 100644 --- a/SignalMessaging/categories/UIFont+OWS.h +++ b/SignalMessaging/categories/UIFont+OWS.h @@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN - (UIFont *)ows_italic; - (UIFont *)ows_bold; -- (UIFont *)ows_medium; +- (UIFont *)ows_mediumWeight; @end diff --git a/SignalMessaging/categories/UIFont+OWS.m b/SignalMessaging/categories/UIFont+OWS.m index 780f86d44..4a114031a 100644 --- a/SignalMessaging/categories/UIFont+OWS.m +++ b/SignalMessaging/categories/UIFont+OWS.m @@ -117,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN return font ?: self; } -- (UIFont *)ows_medium +- (UIFont *)ows_mediumWeight { // The recommended approach of deriving "medium" weight fonts for dynamic // type fonts is: