diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m index fcc555e68..da2972c48 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSContactShareView.m @@ -130,7 +130,7 @@ NS_ASSUME_NONNULL_BEGIN + (CGFloat)iconSize { - return 44.f; + return 48.f; } - (CGFloat)iconSize diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m index dd4c26ede..6270ea826 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageBubbleView.m @@ -447,6 +447,7 @@ NS_ASSUME_NONNULL_BEGIN [self.viewConstraints addObjectsFromArray:@[ [self.footerView autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.textInsetHorizontal], [self.footerView autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.textInsetHorizontal], + [self.footerView autoPinEdgeToSuperviewMargin:ALEdgeTop relation:NSLayoutRelationGreaterThanOrEqual], [self.footerView autoPinBottomToSuperviewMarginWithInset:self.conversationStyle.textInsetBottom], ]]; } else { diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 3a3c2a215..9da6dfdbd 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN // to always keep one around. @property (nonatomic) OWSMessageBubbleView *messageBubbleView; -@property (nonatomic) UIView *dateHeaderView; +@property (nonatomic) UIStackView *dateHeaderView; @property (nonatomic) UIView *dateStrokeView; @property (nonatomic) UILabel *dateHeaderLabel; @property (nonatomic) AvatarImageView *avatarView; @@ -51,23 +51,21 @@ NS_ASSUME_NONNULL_BEGIN self.messageBubbleView = [OWSMessageBubbleView new]; [self.contentView addSubview:self.messageBubbleView]; - self.dateHeaderView = [UIView new]; - self.dateStrokeView = [UIView new]; - self.dateStrokeView.backgroundColor = [UIColor lightGrayColor]; - [self.dateHeaderView addSubview:self.dateStrokeView]; + self.dateStrokeView.backgroundColor = [UIColor ows_light45Color]; + [self.dateStrokeView autoSetDimension:ALDimensionHeight toSize:self.dateHeaderStrokeThickness]; + [self.dateStrokeView setContentHuggingHigh]; self.dateHeaderLabel = [UILabel new]; - self.dateHeaderLabel.font = self.dateHeaderDateFont; + self.dateHeaderLabel.font = self.dateHeaderFont; self.dateHeaderLabel.textAlignment = NSTextAlignmentCenter; - self.dateHeaderLabel.textColor = [UIColor lightGrayColor]; - [self.dateHeaderView addSubview:self.dateHeaderLabel]; + self.dateHeaderLabel.textColor = [UIColor ows_light60Color]; - [self.dateStrokeView autoPinWidthToSuperview]; - [self.dateStrokeView autoPinEdgeToSuperviewEdge:ALEdgeTop]; - [self.dateStrokeView autoSetDimension:ALDimensionHeight toSize:1.f]; - [self.dateHeaderLabel autoPinWidthToSuperview]; - [self.dateHeaderLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.dateStrokeView]; + self.dateHeaderView = [[UIStackView alloc] initWithArrangedSubviews:@[ + self.dateStrokeView, + self.dateHeaderLabel, + ]]; + self.dateHeaderView.axis = NSTextLayoutOrientationVertical; self.avatarView = [[AvatarImageView alloc] init]; [self.avatarView autoSetDimension:ALDimensionWidth toSize:self.avatarSize]; @@ -148,7 +146,7 @@ NS_ASSUME_NONNULL_BEGIN [self.messageBubbleView loadContent]; // Update label fonts to honor dynamic type size. - self.dateHeaderLabel.font = self.dateHeaderDateFont; + self.dateHeaderLabel.font = self.dateHeaderFont; if (self.isIncoming) { [self.viewConstraints addObjectsFromArray:@[ @@ -227,18 +225,18 @@ NS_ASSUME_NONNULL_BEGIN NSAttributedString *attributedText = [NSAttributedString new]; attributedText = [attributedText rtlSafeAppend:dateString.uppercaseString attributes:@{ - NSFontAttributeName : self.dateHeaderDateFont, + NSFontAttributeName : self.dateHeaderFont, NSForegroundColorAttributeName : [UIColor lightGrayColor], } referenceView:self]; attributedText = [attributedText rtlSafeAppend:@" " attributes:@{ - NSFontAttributeName : self.dateHeaderDateFont, + NSFontAttributeName : self.dateHeaderFont, } referenceView:self]; attributedText = [attributedText rtlSafeAppend:timeString attributes:@{ - NSFontAttributeName : self.dateHeaderTimeFont, + NSFontAttributeName : self.dateHeaderFont, NSForegroundColorAttributeName : [UIColor lightGrayColor], } referenceView:self]; @@ -250,9 +248,16 @@ NS_ASSUME_NONNULL_BEGIN [self.dateHeaderView autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.gutterLeading], [self.dateHeaderView autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.gutterTrailing], [self.dateHeaderView autoPinEdgeToSuperviewEdge:ALEdgeTop], - [self.dateHeaderView autoSetDimension:ALDimensionHeight toSize:self.dateHeaderHeight], - [self.messageBubbleView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.dateHeaderView], + // DO NOT pin to the bottom of dateHeaderView. + // + // Being a UIStackView, it doesn't reflect the spacing below the date + // header contents. Instead pin using dateHeaderHeight which includes + // the spacing. + [self.messageBubbleView autoPinEdge:ALEdgeTop + toEdge:ALEdgeTop + ofView:self.dateHeaderView + withOffset:self.dateHeaderHeight], ]]; } else { [self.viewConstraints addObjectsFromArray:@[ @@ -261,12 +266,7 @@ NS_ASSUME_NONNULL_BEGIN } } -- (UIFont *)dateHeaderDateFont -{ - return UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight; -} - -- (UIFont *)dateHeaderTimeFont +- (UIFont *)dateHeaderFont { return UIFont.ows_dynamicTypeCaption1Font; } @@ -368,16 +368,21 @@ NS_ASSUME_NONNULL_BEGIN return cellSize; } +- (CGFloat)dateHeaderStrokeThickness +{ + return CGHairlineWidth(); +} + - (CGFloat)dateHeaderBottomMargin { - return 24.f; + return 20.f; } - (CGFloat)dateHeaderHeight { if (self.viewItem.shouldShowDate) { - CGFloat textHeight = MAX(self.dateHeaderDateFont.capHeight, self.dateHeaderTimeFont.capHeight); - return (CGFloat)ceil(textHeight + self.dateHeaderBottomMargin); + CGFloat textHeight = self.dateHeaderFont.capHeight; + return (CGFloat)ceil(self.dateHeaderStrokeThickness + textHeight + self.dateHeaderBottomMargin); } else { return 0.f; } diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSSystemMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSSystemMessageCell.m index cf80d4939..014d07120 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSSystemMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSSystemMessageCell.m @@ -55,7 +55,6 @@ NS_ASSUME_NONNULL_BEGIN [self.imageView setContentHuggingHigh]; self.titleLabel = [UILabel new]; - self.titleLabel.textColor = [UIColor colorWithRGBHex:0x403e3b]; self.titleLabel.numberOfLines = 0; self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; @@ -80,7 +79,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)configureFonts { // Update cell to reflect changes in dynamic text. - self.titleLabel.font = UIFont.ows_dynamicTypeFootnoteFont; + self.titleLabel.font = UIFont.ows_dynamicTypeSubheadlineFont; } + (NSString *)cellReuseIdentifier @@ -122,14 +121,14 @@ NS_ASSUME_NONNULL_BEGIN - (UIColor *)textColor { - return [UIColor colorWithRGBHex:0x303030]; + return [UIColor ows_light60Color]; } - (UIColor *)iconColorForInteraction:(TSInteraction *)interaction { // "Phone", "Shield" and "Hourglass" icons have a lot of "ink" so they // are less dark for balance. - return [UIColor colorWithRGBHex:0x404040]; + return [UIColor ows_light60Color]; } - (UIImage *)iconForInteraction:(TSInteraction *)interaction diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m index 980675a43..578e55aa3 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m @@ -20,6 +20,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) UILabel *subtitleLabel; @property (nonatomic) UIView *strokeView; @property (nonatomic) NSArray *layoutConstraints; +@property (nonatomic) UIStackView *stackView; @end @@ -45,24 +46,28 @@ NS_ASSUME_NONNULL_BEGIN self.contentView.layoutMargins = UIEdgeInsetsZero; self.strokeView = [UIView new]; - // TODO: color. - self.strokeView.backgroundColor = [UIColor blackColor]; - [self.contentView addSubview:self.strokeView]; + self.strokeView.backgroundColor = [UIColor ows_light60Color]; + [self.strokeView autoSetDimension:ALDimensionHeight toSize:self.strokeThickness]; + [self.strokeView setContentHuggingHigh]; self.titleLabel = [UILabel new]; - // TODO: color. - self.titleLabel.textColor = [UIColor blackColor]; + self.titleLabel.textColor = [UIColor ows_light90Color]; self.titleLabel.textAlignment = NSTextAlignmentCenter; - [self.contentView addSubview:self.titleLabel]; self.subtitleLabel = [UILabel new]; - // TODO: color. - self.subtitleLabel.textColor = [UIColor lightGrayColor]; + self.subtitleLabel.textColor = [UIColor ows_light90Color]; // The subtitle may wrap to a second line. self.subtitleLabel.numberOfLines = 0; self.subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping; self.subtitleLabel.textAlignment = NSTextAlignmentCenter; - [self.contentView addSubview:self.subtitleLabel]; + + self.stackView = [[UIStackView alloc] initWithArrangedSubviews:@[ + self.strokeView, + self.titleLabel, + self.subtitleLabel, + ]]; + self.stackView.axis = NSTextLayoutOrientationVertical; + [self.contentView addSubview:self.stackView]; [self configureFonts]; } @@ -70,8 +75,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)configureFonts { // Update cell to reflect changes in dynamic text. - // - // TODO: Font size. self.titleLabel.font = UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight; self.subtitleLabel.font = UIFont.ows_dynamicTypeCaption1Font; } @@ -94,26 +97,16 @@ NS_ASSUME_NONNULL_BEGIN self.titleLabel.text = [self titleForInteraction:interaction]; self.subtitleLabel.text = [self subtitleForInteraction:interaction]; - self.backgroundColor = [UIColor whiteColor]; + self.subtitleLabel.hidden = self.subtitleLabel.text.length < 1; [NSLayoutConstraint deactivateConstraints:self.layoutConstraints]; self.layoutConstraints = @[ - [self.strokeView autoPinEdgeToSuperviewEdge:ALEdgeTop], - [self.strokeView autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterLeading], - [self.strokeView autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterTrailing], - [self.strokeView autoSetDimension:ALDimensionHeight toSize:self.strokeHeight], - - [self.titleLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.strokeView], - [self.titleLabel autoPinEdgeToSuperviewEdge:ALEdgeTop], - [self.titleLabel autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterLeading], - [self.titleLabel autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterTrailing], - - [self.subtitleLabel autoPinEdge:ALEdgeTop - toEdge:ALEdgeBottom - ofView:self.titleLabel - withOffset:self.subtitleVSpacing], - [self.subtitleLabel autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterLeading], - [self.subtitleLabel autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterTrailing], + [self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTop], + [self.stackView autoPinEdgeToSuperviewEdge:ALEdgeBottom], + [self.stackView autoPinEdgeToSuperviewEdge:ALEdgeLeading + withInset:self.conversationStyle.fullWidthGutterLeading], + [self.stackView autoPinEdgeToSuperviewEdge:ALEdgeTrailing + withInset:self.conversationStyle.fullWidthGutterTrailing], ]; } @@ -135,14 +128,9 @@ NS_ASSUME_NONNULL_BEGIN @"Messages that indicates that there are more unseen messages including safety number changes.")); } -- (CGFloat)strokeHeight -{ - return 1.f; -} - -- (CGFloat)subtitleVSpacing +- (CGFloat)strokeThickness { - return 3.f; + return CGHairlineWidth(); } - (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction @@ -153,13 +141,12 @@ NS_ASSUME_NONNULL_BEGIN [self configureFonts]; - CGSize result - = CGSizeMake(self.conversationStyle.fullWidthContentWidth, self.strokeHeight + self.titleLabel.font.lineHeight); + CGSize result = CGSizeMake( + self.conversationStyle.fullWidthContentWidth, self.strokeThickness + self.titleLabel.font.lineHeight); TSUnreadIndicatorInteraction *interaction = (TSUnreadIndicatorInteraction *)self.viewItem.interaction; self.subtitleLabel.text = [self subtitleForInteraction:interaction]; if (self.subtitleLabel.text.length > 0) { - result.height += self.subtitleVSpacing; result.height += ceil( [self.subtitleLabel sizeThatFits:CGSizeMake(self.conversationStyle.fullWidthContentWidth, CGFLOAT_MAX)] .height); diff --git a/SignalMessaging/categories/UIView+OWS.h b/SignalMessaging/categories/UIView+OWS.h index 68829583a..2cf35217f 100644 --- a/SignalMessaging/categories/UIView+OWS.h +++ b/SignalMessaging/categories/UIView+OWS.h @@ -170,4 +170,6 @@ CG_INLINE CGSize CGSizeMax(CGSize size1, CGSize size2) return CGSizeMake(MAX(size1.width, size2.width), MAX(size1.height, size2.height)); } +CGFloat CGHairlineWidth(); + NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/categories/UIView+OWS.m b/SignalMessaging/categories/UIView+OWS.m index 63e796c01..b82f7dff7 100644 --- a/SignalMessaging/categories/UIView+OWS.m +++ b/SignalMessaging/categories/UIView+OWS.m @@ -542,4 +542,9 @@ CGFloat ScaleFromIPhone5(CGFloat iPhone5Value) @end +CGFloat CGHairlineWidth() +{ + return 1.f / UIScreen.mainScreen.scale; +} + NS_ASSUME_NONNULL_END