Title: [277743] trunk/Source/WebKit
Revision
277743
Author
akeer...@apple.com
Date
2021-05-19 12:32:10 -0700 (Wed, 19 May 2021)

Log Message

[iOS][FCR] <select multiple> picker should collapse sections when tapping anywhere on a group header
https://bugs.webkit.org/show_bug.cgi?id=225974
<rdar://problem/77930033>

Reviewed by Wenson Hsieh.

Currently, the <select multiple> picker only collapses a section when
tapping on the disclosure button on the side of the group header. Instead,
a tap anywhere on the group header should collapse/expand the corresponding
section.

The new behavior is achieved by introducing WKSelectPickerGroupHeaderView,
a view that encapsulates the header label and disclosure icon. A tap
gesture recognizer is added to animate the icon, and notify the its
owner (WKSelectPickerTableViewController) when the view is tapped.

This patch also corrects the icon animation in RTL layouts, and corrects
the spacing between the header label and icon.

* UIProcess/ios/forms/WKFormSelectPicker.mm:
(-[WKSelectPickerGroupHeaderView initWithGroupName:section:]):
(-[WKSelectPickerGroupHeaderView setCollapsed:animated:]):
(-[WKSelectPickerGroupHeaderView setDelegate:]):
(-[WKSelectPickerGroupHeaderView didTapHeader:]):
(+[WKSelectPickerGroupHeaderView preferredFont]):
(+[WKSelectPickerGroupHeaderView preferredMargin]):
(+[WKSelectPickerGroupHeaderView preferredHeight]):
(-[WKSelectPickerTableViewController tableView:heightForHeaderInSection:]):
(-[WKSelectPickerTableViewController tableView:viewForHeaderInSection:]):
(-[WKSelectPickerTableViewController didTapSelectPickerGroupHeaderView:]):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (277742 => 277743)


--- trunk/Source/WebKit/ChangeLog	2021-05-19 19:15:51 UTC (rev 277742)
+++ trunk/Source/WebKit/ChangeLog	2021-05-19 19:32:10 UTC (rev 277743)
@@ -1,3 +1,36 @@
+2021-05-19  Aditya Keerthi  <akeer...@apple.com>
+
+        [iOS][FCR] <select multiple> picker should collapse sections when tapping anywhere on a group header
+        https://bugs.webkit.org/show_bug.cgi?id=225974
+        <rdar://problem/77930033>
+
+        Reviewed by Wenson Hsieh.
+
+        Currently, the <select multiple> picker only collapses a section when
+        tapping on the disclosure button on the side of the group header. Instead,
+        a tap anywhere on the group header should collapse/expand the corresponding
+        section.
+
+        The new behavior is achieved by introducing WKSelectPickerGroupHeaderView,
+        a view that encapsulates the header label and disclosure icon. A tap
+        gesture recognizer is added to animate the icon, and notify the its
+        owner (WKSelectPickerTableViewController) when the view is tapped.
+
+        This patch also corrects the icon animation in RTL layouts, and corrects
+        the spacing between the header label and icon.
+
+        * UIProcess/ios/forms/WKFormSelectPicker.mm:
+        (-[WKSelectPickerGroupHeaderView initWithGroupName:section:]):
+        (-[WKSelectPickerGroupHeaderView setCollapsed:animated:]):
+        (-[WKSelectPickerGroupHeaderView setDelegate:]):
+        (-[WKSelectPickerGroupHeaderView didTapHeader:]):
+        (+[WKSelectPickerGroupHeaderView preferredFont]):
+        (+[WKSelectPickerGroupHeaderView preferredMargin]):
+        (+[WKSelectPickerGroupHeaderView preferredHeight]):
+        (-[WKSelectPickerTableViewController tableView:heightForHeaderInSection:]):
+        (-[WKSelectPickerTableViewController tableView:viewForHeaderInSection:]):
+        (-[WKSelectPickerTableViewController didTapSelectPickerGroupHeaderView:]):
+
 2021-05-19  Sam Weinig  <wei...@apple.com>
 
         Update Base64 encoding/decoding to match more modern WebKit conventions

Modified: trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm (277742 => 277743)


--- trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm	2021-05-19 19:15:51 UTC (rev 277742)
+++ trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm	2021-05-19 19:32:10 UTC (rev 277743)
@@ -740,16 +740,125 @@
 
 @end
 
+@interface WKSelectPickerGroupHeaderView : UIView
+@property (nonatomic, readonly) NSInteger section;
+@end
+
+@interface WKSelectPickerTableViewController : UITableViewController
+- (void)didTapSelectPickerGroupHeaderView:(WKSelectPickerGroupHeaderView *)headerView;
+@end
+
+static const CGFloat groupHeaderMargin = 16.0f;
+static const CGFloat groupHeaderLabelImageMargin = 4.0f;
+static const CGFloat groupHeaderCollapseButtonTransitionDuration = 0.3f;
+
+@implementation WKSelectPickerGroupHeaderView {
+    RetainPtr<UILabel> _label;
+    RetainPtr<UIImageView> _collapseIndicatorView;
+
+    WeakObjCPtr<WKSelectPickerTableViewController> _tableViewController;
+
+    BOOL _collapsed;
+}
+
+- (instancetype)initWithGroupName:(NSString *)groupName section:(NSInteger)section
+{
+    if (!(self = [super init]))
+        return nil;
+
+    _section = section;
+
+    auto tapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapHeader:)]);
+    [self addGestureRecognizer:tapGestureRecognizer.get()];
+
+    _label = adoptNS([[UILabel alloc] init]);
+    [_label setText:groupName];
+    [_label setFont:WKSelectPickerGroupHeaderView.preferredFont];
+    [_label setAdjustsFontForContentSizeCategory:YES];
+    [_label setAdjustsFontSizeToFitWidth:NO];
+    [_label setLineBreakMode:NSLineBreakByTruncatingTail];
+    [self addSubview:_label.get()];
+
+    _collapseIndicatorView = adoptNS([[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"chevron.down"]]);
+    [_collapseIndicatorView setPreferredSymbolConfiguration:[UIImageSymbolConfiguration configurationWithFont:WKSelectPickerGroupHeaderView.preferredFont scale:UIImageSymbolScaleSmall]];
+    [_collapseIndicatorView setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
+    [self addSubview:_collapseIndicatorView.get()];
+
+    [_label setTranslatesAutoresizingMaskIntoConstraints:NO];
+    [NSLayoutConstraint activateConstraints:@[
+        [[_label leadingAnchor] constraintEqualToAnchor:[self leadingAnchor] constant:WKSelectPickerGroupHeaderView.preferredMargin],
+        [[_label trailingAnchor] constraintEqualToAnchor:[_collapseIndicatorView leadingAnchor] constant:-groupHeaderLabelImageMargin],
+        [[_label topAnchor] constraintEqualToAnchor:[self topAnchor] constant:0],
+    ]];
+
+    [_collapseIndicatorView setTranslatesAutoresizingMaskIntoConstraints:NO];
+    [NSLayoutConstraint activateConstraints:@[
+        [[_collapseIndicatorView trailingAnchor] constraintEqualToAnchor:[self trailingAnchor] constant:-WKSelectPickerGroupHeaderView.preferredMargin],
+        [[_collapseIndicatorView topAnchor] constraintEqualToAnchor:[_label topAnchor] constant:0],
+        [[_collapseIndicatorView bottomAnchor] constraintEqualToAnchor:[_label bottomAnchor] constant:0],
+    ]];
+
+    return self;
+}
+
+- (void)setCollapsed:(BOOL)collapsed animated:(BOOL)animated
+{
+    if (_collapsed == collapsed)
+        return;
+
+    _collapsed = collapsed;
+
+    auto animations = [protectedSelf = retainPtr(self)] {
+        auto layoutDirectionMultipler = ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:[protectedSelf semanticContentAttribute]] == UIUserInterfaceLayoutDirectionLeftToRight) ? -1.0f : 1.0f;
+        auto transform = protectedSelf->_collapsed ? CGAffineTransformMakeRotation(layoutDirectionMultipler * M_PI / 2) : CGAffineTransformIdentity;
+        [protectedSelf->_collapseIndicatorView setTransform:transform];
+    };
+
+    if (animated)
+        [UIView animateWithDuration:groupHeaderCollapseButtonTransitionDuration animations:animations];
+    else
+        animations();
+}
+
+- (void)setTableViewController:(WKSelectPickerTableViewController *)tableViewController
+{
+    _tableViewController = tableViewController;
+}
+
+- (void)didTapHeader:(id)sender
+{
+    [_tableViewController didTapSelectPickerGroupHeaderView:self];
+    [self setCollapsed:!_collapsed animated:YES];
+}
+
++ (UIFont *)preferredFont
+{
+    UIFontDescriptor *descriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleTitle3];
+    descriptor = [descriptor fontDescriptorByAddingAttributes:@{
+        UIFontDescriptorTraitsAttribute: @{
+            UIFontWeightTrait: @(UIFontWeightSemibold)
+        }
+    }];
+
+    return [UIFont fontWithDescriptor:descriptor size:0];
+}
+
++ (CGFloat)preferredMargin
+{
+    return groupHeaderMargin;
+}
+
++ (CGFloat)preferredHeight
+{
+    return WKSelectPickerGroupHeaderView.preferredFont.lineHeight + WKSelectPickerGroupHeaderView.preferredMargin;
+}
+
+@end
+
 static const CGFloat nextPreviousSpacerWidth = 6.0f;
-static const CGFloat sectionHeaderCollapseButtonSize = 14.0f;
-static const CGFloat sectionHeaderCollapseButtonTransitionDuration = 0.2f;
-static const CGFloat sectionHeaderMargin = 16.0f;
 static const CGFloat selectPopoverLength = 320.0f;
 static NSString *optionCellReuseIdentifier = @"WKSelectPickerTableViewCell";
 
-@interface WKSelectPickerTableViewController : UITableViewController
-@end
-
 @implementation WKSelectPickerTableViewController {
     __weak WKContentView *_contentView;
 
@@ -838,7 +947,7 @@
     if (!section)
         return tableView.layoutMargins.left;
 
-    return self.groupHeaderFont.lineHeight + sectionHeaderMargin;
+    return WKSelectPickerGroupHeaderView.preferredHeight;
 }
 
 - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
@@ -877,44 +986,16 @@
     if (!section)
         return nil;
 
-    auto sectionView = adoptNS([[UIView alloc] init]);
+    auto headerView = adoptNS([[WKSelectPickerGroupHeaderView alloc] initWithGroupName:[self tableView:tableView titleForHeaderInSection:section] section:section]);
+    [headerView setCollapsed:[_collapsedSections containsObject:@(section)] animated:NO];
+    [headerView setTableViewController:self];
 
-    auto sectionLabel = adoptNS([[UILabel alloc] init]);
-    [sectionLabel setText:[self tableView:tableView titleForHeaderInSection:section]];
-    [sectionLabel setFont:self.groupHeaderFont];
-    [sectionLabel setAdjustsFontForContentSizeCategory:YES];
-    [sectionLabel setAdjustsFontSizeToFitWidth:NO];
-    [sectionLabel setLineBreakMode:NSLineBreakByTruncatingTail];
-    [sectionView addSubview:sectionLabel.get()];
-
-    [sectionLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
-    [NSLayoutConstraint activateConstraints:@[
-        [[sectionLabel leadingAnchor] constraintEqualToAnchor:[sectionView leadingAnchor] constant:sectionHeaderMargin],
-        [[sectionLabel topAnchor] constraintEqualToAnchor:[sectionView topAnchor] constant:0],
-    ]];
-
-    auto collapseButton = adoptNS([[UIButton alloc] init]);
-    [collapseButton setTag:section];
-    [collapseButton setImage:[UIImage systemImageNamed:@"chevron.down" withConfiguration:[UIImageSymbolConfiguration configurationWithPointSize:sectionHeaderCollapseButtonSize weight:UIImageSymbolWeightSemibold]] forState:UIControlStateNormal];
-    [collapseButton addTarget:self action:@selector(collapseSection:) forControlEvents:UIControlEventTouchUpInside];
-    [sectionView addSubview:collapseButton.get()];
-
-    if ([_collapsedSections containsObject:@(section)])
-        [collapseButton setTransform:CGAffineTransformMakeRotation(-M_PI / 2)];
-
-    [collapseButton setTranslatesAutoresizingMaskIntoConstraints:NO];
-    [NSLayoutConstraint activateConstraints:@[
-        [[collapseButton trailingAnchor] constraintEqualToAnchor:[sectionView trailingAnchor] constant:-sectionHeaderMargin],
-        [[collapseButton topAnchor] constraintEqualToAnchor:[sectionLabel topAnchor] constant:0],
-        [[collapseButton bottomAnchor] constraintEqualToAnchor:[sectionLabel bottomAnchor] constant:0],
-    ]];
-
-    return sectionView.autorelease();
+    return headerView.autorelease();
 }
 
-- (void)collapseSection:(UIButton *)button
+- (void)didTapSelectPickerGroupHeaderView:(WKSelectPickerGroupHeaderView *)headerView
 {
-    NSInteger section = button.tag;
+    NSInteger section = headerView.section;
     NSInteger rowCount = [self numberOfRowsInGroup:section];
 
     NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:rowCount];
@@ -929,13 +1010,6 @@
         [_collapsedSections addObject:object];
         [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
     }
-
-    [UIView animateWithDuration:sectionHeaderCollapseButtonTransitionDuration animations:^{
-        if (CGAffineTransformEqualToTransform(button.transform, CGAffineTransformIdentity))
-            button.transform = CGAffineTransformMakeRotation(-M_PI / 2);
-        else
-            button.transform = CGAffineTransformIdentity;
-    }];
 }
 
 - (NSInteger)findItemIndexAt:(NSIndexPath *)indexPath
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to