Brion VIBBER has submitted this change and it was merged. Change subject: Table of contents refinements. ......................................................................
Table of contents refinements. Change-Id: I5b2b728fb804034919460e7a5afd72fe3eb9ca56 --- M wikipedia/Base.lproj/Main_iPhone.storyboard M wikipedia/View Controllers/TableOfContents/TOCSectionCellView.m M wikipedia/View Controllers/TableOfContents/TOCViewController.m M wikipedia/View Controllers/WebView/WebViewController.m M wikipedia/en.lproj/Localizable.strings M wikipedia/qqq.lproj/Localizable.strings 6 files changed, 117 insertions(+), 65 deletions(-) Approvals: Brion VIBBER: Verified; Looks good to me, approved diff --git a/wikipedia/Base.lproj/Main_iPhone.storyboard b/wikipedia/Base.lproj/Main_iPhone.storyboard index cfd1212..7de9052 100644 --- a/wikipedia/Base.lproj/Main_iPhone.storyboard +++ b/wikipedia/Base.lproj/Main_iPhone.storyboard @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5056" systemVersion="13D65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="1qV-3k-dN1"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5056" systemVersion="13E28" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="1qV-3k-dN1"> <dependencies> <deployment defaultVersion="1536" identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/> @@ -108,7 +108,7 @@ </constraints> </view> </subviews> - <color key="backgroundColor" red="0.22052375637755106" green="0.22052375637755106" blue="0.22052375637755106" alpha="1" colorSpace="calibratedRGB"/> + <color key="backgroundColor" red="0.047058828175067902" green="0.047058828175067902" blue="0.047058828175067902" alpha="1" colorSpace="deviceRGB"/> <constraints> <constraint firstItem="VGj-z3-9mh" firstAttribute="leading" secondItem="sgu-W1-m18" secondAttribute="leading" id="jVV-fN-1Va"/> <constraint firstAttribute="bottom" secondItem="VGj-z3-9mh" secondAttribute="bottom" id="jvc-8X-PKF"/> @@ -1254,9 +1254,9 @@ <constraints> <constraint firstItem="WeL-Mj-Zsh" firstAttribute="top" secondItem="C8y-0k-FBq" secondAttribute="bottom" id="3Gh-gP-O56"/> <constraint firstItem="WeL-Mj-Zsh" firstAttribute="leading" secondItem="kh9-bI-dsS" secondAttribute="leading" id="3Zs-jL-a48"/> - <constraint firstItem="WeL-Mj-Zsh" firstAttribute="leading" secondItem="F4Q-Xc-ImV" secondAttribute="leading" id="87k-zE-vFH"/> - <constraint firstAttribute="trailing" secondItem="F4Q-Xc-ImV" secondAttribute="trailing" id="D19-HH-fX5"/> + <constraint firstItem="WeL-Mj-Zsh" firstAttribute="trailing" secondItem="F4Q-Xc-ImV" secondAttribute="trailing" id="J2p-jy-zrW"/> <constraint firstAttribute="trailing" secondItem="WeL-Mj-Zsh" secondAttribute="trailing" id="QSr-uN-iN4"/> + <constraint firstItem="WeL-Mj-Zsh" firstAttribute="leading" secondItem="F4Q-Xc-ImV" secondAttribute="leading" id="akc-jF-1Pw"/> <constraint firstAttribute="bottom" secondItem="F4Q-Xc-ImV" secondAttribute="bottom" placeholder="YES" id="bOy-uv-taw"/> <constraint firstAttribute="bottom" secondItem="WeL-Mj-Zsh" secondAttribute="bottom" id="myK-xK-1sX"/> </constraints> diff --git a/wikipedia/View Controllers/TableOfContents/TOCSectionCellView.m b/wikipedia/View Controllers/TableOfContents/TOCSectionCellView.m index 8e9c5d7..b5b559c 100644 --- a/wikipedia/View Controllers/TableOfContents/TOCSectionCellView.m +++ b/wikipedia/View Controllers/TableOfContents/TOCSectionCellView.m @@ -9,6 +9,9 @@ #import "WMF_Colors.h" #import "UIView+RemoveConstraints.h" #import "Section+LeadSection.h" +#import "NSString+FormattedAttributedString.h" +#import "WikipediaAppUtils.h" +#import "SessionSingleton.h" @interface TOCSectionCellView(){ @@ -16,12 +19,8 @@ @property (nonatomic, strong) UILabel *titleLabel; -@property (nonatomic) CGFloat indentMargin; -@property (nonatomic) CGFloat indentMarginMin; - -@property (nonatomic) CGFloat imageIndentMargin; -@property (nonatomic) CGFloat imageIndentMarginMin; -@property (nonatomic) CGFloat imageMargin; +@property (nonatomic) UIEdgeInsets cellMargin; +@property (nonatomic) UIEdgeInsets imageMargin; @property (nonatomic) CGSize imageSize; @property (nonatomic, strong) NSNumber *tocLevel; @@ -49,14 +48,9 @@ [self addSubview:self.titleLabel]; - self.indentMargin = 0.0f; - self.indentMarginMin = 6.0f; - - self.imageIndentMargin = 0.0f; - self.imageIndentMarginMin = 6.0f; - - self.imageMargin = 6.0f; - self.imageSize = CGSizeMake(60.0f, 40.0f); + self.cellMargin = UIEdgeInsetsMake(8, 12, 8, 10); + self.imageMargin = UIEdgeInsetsMake(5, 5, 5, 0); + self.imageSize = CGSizeMake(52.5f, 35.0f); self.isHighlighted = NO; @@ -73,31 +67,73 @@ -(void)setIsHighlighted:(BOOL)isHighlighted { if (isHighlighted) { - self.backgroundColor = WMF_COLOR_BLUE; + self.backgroundColor = [WMF_COLOR_BLUE colorWithAlphaComponent:0.6]; }else{ - self.backgroundColor = [UIColor darkGrayColor]; + self.backgroundColor = [UIColor colorWithRed:0.049 green:0.049 blue:0.049 alpha:1.0]; } if (isHighlighted) self.alpha = 1.0f; _isHighlighted = isHighlighted; + + [self adjustFontColorForHighlightedState]; +} + +-(void)adjustFontColorForHighlightedState +{ + // Only changes the text color. + NSMutableAttributedString *mutableString = + [[NSMutableAttributedString alloc] initWithAttributedString:self.titleLabel.attributedText]; + + UIColor *color = self.isHighlighted ? + [UIColor whiteColor] + : + [UIColor colorWithRed:0.573 green:0.58 blue:0.592 alpha:1]; + + [mutableString addAttributes: @{NSForegroundColorAttributeName : color} + range: NSMakeRange(0, self.titleLabel.attributedText.length)]; + + self.titleLabel.attributedText = mutableString; } -(NSAttributedString *)getAttributedStringForString:(NSString *)str isLeadSection:(BOOL)isLeadSection { - NSUInteger fontSize = (isLeadSection) ? 22 : 15; - NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.alignment = NSTextAlignmentLeft; - return [[NSMutableAttributedString alloc] - initWithString:str attributes: @{ - NSFontAttributeName : [UIFont systemFontOfSize:fontSize], - NSParagraphStyleAttributeName : paragraphStyle, - NSStrokeWidthAttributeName : @0.0f, //@-1.0f, - NSStrokeColorAttributeName : [UIColor blackColor], - NSForegroundColorAttributeName : [UIColor whiteColor], - }]; + if (!isLeadSection) { + + return [[NSMutableAttributedString alloc] + initWithString:str attributes: @{ + NSFontAttributeName : [UIFont systemFontOfSize:15], + NSParagraphStyleAttributeName : paragraphStyle, + NSStrokeWidthAttributeName : @0.0f, //@-1.0f, + NSStrokeColorAttributeName : [UIColor blackColor], + NSForegroundColorAttributeName : [UIColor whiteColor], + }]; + }else{ + + NSDictionary *topAttributes = @{ + NSFontAttributeName : [UIFont systemFontOfSize:10], + NSKernAttributeName : @(1.5), + NSForegroundColorAttributeName : [UIColor whiteColor] + }; + NSDictionary *bottomAttributes = @{ + NSFontAttributeName : [UIFont fontWithName:@"Times New Roman" size:22], + NSForegroundColorAttributeName : [UIColor whiteColor] + }; + + NSString *heading = MWLocalizedString(@"table-of-contents-heading", nil); + + if ([[SessionSingleton sharedInstance].domain isEqualToString:@"en"]) { + heading = [heading uppercaseString]; + } + + return [@"$1\n$2" attributedStringWithAttributes: @{} + substitutionStrings: @[heading, str] + substitutionAttributes: @[topAttributes, bottomAttributes] + ]; + } } -(NSAttributedString *)getAttributedTitleForSection:(Section *)section @@ -228,15 +264,15 @@ imageView.layer.borderWidth = 1.0 / [UIScreen mainScreen].scale; // Default layout with horizontal row of images beneath title label. - constrain(imageView, NSLayoutAttributeBottom, self, NSLayoutAttributeBottom, -self.imageMargin); + constrain(imageView, NSLayoutAttributeBottom, self, NSLayoutAttributeBottom, -self.imageMargin.bottom); constrain(imageView, NSLayoutAttributeWidth, nil, NSLayoutAttributeNotAnAttribute, self.imageSize.width); constrain(imageView, NSLayoutAttributeHeight, nil, NSLayoutAttributeNotAnAttribute, self.imageSize.height); if (self.sectionImageViews.firstObject == imageView) { - constrain(imageView, NSLayoutAttributeTop, self.titleLabel, NSLayoutAttributeBottom, self.imageMargin); - constrain(imageView, NSLayoutAttributeLeft, self, NSLayoutAttributeLeft, (tocLevel.floatValue * self.imageIndentMargin) + self.imageIndentMarginMin); + constrain(imageView, NSLayoutAttributeTop, self.titleLabel, NSLayoutAttributeBottom, self.imageMargin.top); + constrain(imageView, NSLayoutAttributeLeft, self, NSLayoutAttributeLeft, self.cellMargin.left); } if (prevImage) { - constrain(imageView, NSLayoutAttributeLeft, prevImage, NSLayoutAttributeRight, self.imageMargin); + constrain(imageView, NSLayoutAttributeLeft, prevImage, NSLayoutAttributeRight, self.imageMargin.left); } prevImage = imageView; @@ -252,10 +288,10 @@ constrain(imageView, NSLayoutAttributeTop, self.titleLabel, NSLayoutAttributeBottom, 0); } if (self.sectionImageViews.lastObject == imageView) { - constrain(imageView, NSLayoutAttributeBottom, self, NSLayoutAttributeBottom, -self.imageMargin); + constrain(imageView, NSLayoutAttributeBottom, self, NSLayoutAttributeBottom, -self.imageMargin.bottom); } if (prevImage) { - constrain(imageView, NSLayoutAttributeTop, prevImage, NSLayoutAttributeBottom, self.imageMargin); + constrain(imageView, NSLayoutAttributeTop, prevImage, NSLayoutAttributeBottom, self.imageMargin.top); } prevImage = imageView; } @@ -277,11 +313,10 @@ [self addConstraint:constraint]; }; - NSInteger tocLevelToUse = ((self.tocLevel.intValue - 1) < 0) ? 0 : self.tocLevel.intValue - 1; - constrainTitleLabel(NSLayoutAttributeLeft, (tocLevelToUse * self.indentMargin) + self.indentMarginMin); - constrainTitleLabel(NSLayoutAttributeRight, -5); - constrainTitleLabel(NSLayoutAttributeTop, 5); - constrainTitleLabel(NSLayoutAttributeBottom, -5); + constrainTitleLabel(NSLayoutAttributeLeft, self.cellMargin.left); + constrainTitleLabel(NSLayoutAttributeRight, -self.cellMargin.right); + constrainTitleLabel(NSLayoutAttributeTop, self.cellMargin.top); + constrainTitleLabel(NSLayoutAttributeBottom, -self.cellMargin.bottom); // The label's instrinsic content size will keep it above "1" height. This allows labels above // images to be narrower vertically than a label for a section which has no images. @@ -387,8 +422,7 @@ [self.titleLabel removeConstraintsOfViewFromView:self]; - NSInteger tocLevelToUse = ((self.tocLevel.intValue - 1) < 0) ? 0 : self.tocLevel.intValue - 1; - constrain(self.titleLabel, NSLayoutAttributeLeft, NSLayoutRelationEqual, self, NSLayoutAttributeLeft, (tocLevelToUse * self.indentMargin) + self.indentMarginMin); + constrain(self.titleLabel, NSLayoutAttributeLeft, NSLayoutRelationEqual, self, NSLayoutAttributeLeft, self.cellMargin.left); constrain(self.titleLabel, NSLayoutAttributeRight, NSLayoutRelationEqual, self, NSLayoutAttributeRight, -5); constrain(self.titleLabel, NSLayoutAttributeTop, NSLayoutRelationEqual, self, NSLayoutAttributeTop, 5); constrain(self.titleLabel, NSLayoutAttributeBottom, NSLayoutRelationEqual, self, NSLayoutAttributeBottom, -5); diff --git a/wikipedia/View Controllers/TableOfContents/TOCViewController.m b/wikipedia/View Controllers/TableOfContents/TOCViewController.m index a2e4166..88600cd 100644 --- a/wikipedia/View Controllers/TableOfContents/TOCViewController.m +++ b/wikipedia/View Controllers/TableOfContents/TOCViewController.m @@ -14,7 +14,7 @@ #import "UIView+RemoveConstraints.h" #import "TOCImageView.h" -#define TOC_SECTION_MARGIN (1.0f / [UIScreen mainScreen].scale) +#define TOC_SECTION_MARGIN 0 //(1.0f / [UIScreen mainScreen].scale) #define TOC_SELECTION_OFFSET_Y 48.0f #define TOC_DELAY_BETWEEN_SELECTION_AND_ZOOM 0.35f #define TOC_TAG_OTHER_LANGUAGES 9999 @@ -569,7 +569,7 @@ UIView *prevCell = nil; for (UIView *cell in self.sectionCells) { constrain(cell, NSLayoutAttributeLeft, self.scrollContainer, NSLayoutAttributeLeft, 0.0f); - constrain(cell, NSLayoutAttributeRight, self.scrollContainer, NSLayoutAttributeRight, 0.0f); + constrain(cell, NSLayoutAttributeRight, self.scrollContainer, NSLayoutAttributeRight, (1.0f / [UIScreen mainScreen].scale)); if (self.sectionCells.firstObject == cell) { constrain(cell, NSLayoutAttributeTop, self.scrollContainer, NSLayoutAttributeTop, TOC_SECTION_MARGIN); } diff --git a/wikipedia/View Controllers/WebView/WebViewController.m b/wikipedia/View Controllers/WebView/WebViewController.m index a6431d6..2fb8b8a 100644 --- a/wikipedia/View Controllers/WebView/WebViewController.m +++ b/wikipedia/View Controllers/WebView/WebViewController.m @@ -506,7 +506,7 @@ -(BOOL)tocDrawerIsOpen { - return (self.webViewLeftConstraint.constant == 0) ? NO : YES; + return (self.webViewRightConstraint.constant == 0) ? NO : YES; } -(void)tocHideIfSafeToToggleDuringNextRunLoopWithDuration:(NSNumber *)duration @@ -535,13 +535,12 @@ animations: ^{ // If the top menu isn't hidden, reveal the bottom menu. - if(!ROOT.topMenuHidden){ - self.bottomMenuHidden = NO; - [self.view setNeedsUpdateConstraints]; - } + self.bottomMenuHidden = ROOT.topMenuHidden; + [self.view setNeedsUpdateConstraints]; + self.webView.transform = CGAffineTransformIdentity; self.bottomBarView.transform = CGAffineTransformIdentity; - self.webViewLeftConstraint.constant = 0; + self.webViewRightConstraint.constant = 0; [self.view layoutIfNeeded]; }completion: ^(BOOL done){ @@ -592,7 +591,7 @@ [self.view setNeedsUpdateConstraints]; self.webView.transform = xf; self.bottomBarView.transform = xf; - self.webViewLeftConstraint.constant = [self tocGetWidthForWebViewScale:webViewScale]; + self.webViewRightConstraint.constant = [self tocGetWidthForWebViewScale:webViewScale]; [self.view layoutIfNeeded]; }completion: ^(BOOL done){ [self.view setNeedsUpdateConstraints]; @@ -652,6 +651,11 @@ } } +-(BOOL)isDeviceLanguageRTL { + // From: http://stackoverflow.com/a/14793934 + return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft); +} + -(void)tocSetupSwipeGestureRecognizers { self.tocSwipeLeftRecognizer = @@ -661,12 +665,15 @@ self.tocSwipeRightRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget: self action: @selector(tocSwipeRightHandler:)]; + + // Device rtl value is checked since this is what would cause the other constraints to flip. + BOOL isRTL = [self isDeviceLanguageRTL]; [self tocSetupSwipeGestureRecognizer: self.tocSwipeLeftRecognizer - forDirection: UISwipeGestureRecognizerDirectionLeft]; + forDirection: (isRTL ? UISwipeGestureRecognizerDirectionRight : UISwipeGestureRecognizerDirectionLeft)]; [self tocSetupSwipeGestureRecognizer: self.tocSwipeRightRecognizer - forDirection: UISwipeGestureRecognizerDirectionRight]; + forDirection: (isRTL ? UISwipeGestureRecognizerDirectionLeft : UISwipeGestureRecognizerDirectionRight)]; } -(void)tocSetupSwipeGestureRecognizer: (UISwipeGestureRecognizer *)recognizer @@ -685,13 +692,6 @@ -(void)tocSwipeLeftHandler:(UISwipeGestureRecognizer *)recognizer { - if (recognizer.state == UIGestureRecognizerStateEnded){ - [self tocHide]; - } -} - --(void)tocSwipeRightHandler:(UISwipeGestureRecognizer *)recognizer -{ NSString *currentArticleTitle = [SessionSingleton sharedInstance].currentArticleTitle; if (!currentArticleTitle || (currentArticleTitle.length == 0)) return; @@ -700,13 +700,28 @@ } } +-(void)tocSwipeRightHandler:(UISwipeGestureRecognizer *)recognizer +{ + if (recognizer.state == UIGestureRecognizerStateEnded){ + [self tocHide]; + } +} + -(CGFloat)tocGetWebViewScaleWhenTOCVisible { + CGFloat scale = 1.0; if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){ - return (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 0.67f : 0.72f); + scale = (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 0.67f : 0.72f); }else{ - return (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 0.45f : 0.65f); + scale = (UIInterfaceOrientationIsPortrait(self.interfaceOrientation) ? 0.49f : 0.65f); } + + // Adjust scale so it won't result in fractional pixel width when applied to web view width. + // This prevents the web view from jumping a bit w/long pages. + NSInteger i = (NSInteger)self.view.frame.size.width * scale; + CGFloat cleanScale = (i / self.view.frame.size.width); + + return cleanScale; } -(CGFloat)tocGetWidthForWebViewScale:(CGFloat)webViewScale @@ -736,10 +751,10 @@ @[ @[ [NSLayoutConstraint constraintWithItem: self.tocVC.view - attribute: NSLayoutAttributeRight + attribute: NSLayoutAttributeLeading // "Leading" for rtl langs. relatedBy: NSLayoutRelationEqual toItem: self.webView - attribute: NSLayoutAttributeLeft + attribute: NSLayoutAttributeTrailing // "Trailing" for rtl langs. multiplier: 1.0 constant: 0] ] diff --git a/wikipedia/en.lproj/Localizable.strings b/wikipedia/en.lproj/Localizable.strings index 5d02d58..296e62d 100644 --- a/wikipedia/en.lproj/Localizable.strings +++ b/wikipedia/en.lproj/Localizable.strings @@ -168,3 +168,5 @@ "license-footer-text" = "Content is available under $1"; "license-footer-name" = "CC-BY-SA 3.0"; + +"table-of-contents-heading" = "Contents"; diff --git a/wikipedia/qqq.lproj/Localizable.strings b/wikipedia/qqq.lproj/Localizable.strings index 31a3f88..2e6935f 100644 --- a/wikipedia/qqq.lproj/Localizable.strings +++ b/wikipedia/qqq.lproj/Localizable.strings @@ -145,3 +145,4 @@ "preference_summary_eventlogging_opt_in" = "Description of preference that when checked enables data collection of user behavior."; "license-footer-text" = "Brief footer text linking to CC-BY-SA license. '$1' is placeholder for the license-footer-name message"; "license-footer-name" = "License short name; usually leave untranslated as CC-BY-SA 3.0"; +"table-of-contents-heading" = "Header text appearing above the first section in the table of contents"; -- To view, visit https://gerrit.wikimedia.org/r/144597 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I5b2b728fb804034919460e7a5afd72fe3eb9ca56 Gerrit-PatchSet: 1 Gerrit-Project: apps/ios/wikipedia Gerrit-Branch: master Gerrit-Owner: Mhurd <mh...@wikimedia.org> Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits