Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add progressViewOffset on iOS #11356

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Examples/UIExplorer/js/RefreshControlExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class RefreshControlExample extends React.Component {
titleColor="#00ff00"
colors={['#ff0000', '#00ff00', '#0000ff']}
progressBackgroundColor="#ffff00"
progressViewOffset={0}
/>
}>
{rows}
Expand Down
1 change: 0 additions & 1 deletion Libraries/Components/RefreshControl/RefreshControl.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ const RefreshControl = React.createClass({
size: React.PropTypes.oneOf([RefreshLayoutConsts.SIZE.DEFAULT, RefreshLayoutConsts.SIZE.LARGE]),
/**
* Progress view top offset
* @platform android
*/
progressViewOffset: React.PropTypes.number,
},
Expand Down
48 changes: 27 additions & 21 deletions React/Views/RCTRefreshControl.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
@implementation RCTRefreshControl {
BOOL _isInitialRender;
BOOL _currentRefreshingState;
NSString *_title;
UIColor *_titleColor;
float _progressViewOffset;
}

- (instancetype)init
Expand All @@ -33,6 +32,18 @@ - (instancetype)init
- (void)layoutSubviews
{
[super layoutSubviews];

// UIRefreshControl is managed so avoid changing it directly
// This method may break in future versions of iOS (subview structure may change)
// And self.transform won't shift title text
if(_isInitialRender) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what view are we looking for? can we be more certain that it's the right one.
also I would a better explanation as to what view you're looking for so that whomever has to fix this when it breaks knows what to do :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion, @mmmulani! I actually forgot about that I could inspect the UI layers.
I'm thinking of this, which seems to work:

NSString *subviewClass = NSStringFromClass([subview class]);
if([subviewClass isEqualToString:@"_UIRefreshControlModernContentView"]) { ... }

I will look into adding a test instead of doing this runtime this week.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking a look at this PR again. I'm concerned about the code here. It's been a while since I've worked on iOS and I am not sure about what current best practices are. @mmmulani do you approve of this method for finding the progress view subview?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, cc @brentvatne since it sounded like you were interested in this PR. Can you take a look?

UIView *subview = self.subviews.firstObject;
if(subview != nil) {
CGRect rect = subview.bounds;
rect.origin.y = -_progressViewOffset;
subview.bounds = rect;
}
}

// Fix for bug #7976
// TODO: Remove when updating to use iOS 10 refreshControl UIScrollView prop.
Expand Down Expand Up @@ -88,33 +99,23 @@ - (void)endRefreshing

- (NSString *)title
{
return _title;
return self.attributedTitle.string;
}

- (void)setTitle:(NSString *)title
{
_title = title;
[self _updateTitle];
NSRange range = NSMakeRange(0, self.attributedTitle.length);
NSDictionary *attrs = [self.attributedTitle attributesAtIndex:0 effectiveRange: &range];
self.attributedTitle = [[NSAttributedString alloc] initWithString:title attributes:attrs];
}

- (void)setTitleColor:(UIColor *)color
{
_titleColor = color;
[self _updateTitle];
}

- (void)_updateTitle
{
if (!_title) {
return;
}

NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
if (_titleColor) {
attributes[NSForegroundColorAttributeName] = _titleColor;
}

self.attributedTitle = [[NSAttributedString alloc] initWithString:_title attributes:attributes];
NSRange range = NSMakeRange(0, self.attributedTitle.length);
NSDictionary *attrs = [self.attributedTitle attributesAtIndex:0 effectiveRange: &range];
NSMutableDictionary *attrsMutable = [attrs mutableCopy];
[attrsMutable setObject:color forKey:NSForegroundColorAttributeName];
self.attributedTitle = [[NSAttributedString alloc] initWithString:self.attributedTitle.string attributes:attrsMutable];
}

- (void)setRefreshing:(BOOL)refreshing
Expand All @@ -132,6 +133,11 @@ - (void)setRefreshing:(BOOL)refreshing
}
}

- (void)setProgressViewOffset:(float)offset
{
_progressViewOffset = offset;
}

- (void)refreshControlValueChanged
{
_currentRefreshingState = super.refreshing;
Expand Down
1 change: 1 addition & 0 deletions React/Views/RCTRefreshControlManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(title, NSString)
RCT_EXPORT_VIEW_PROPERTY(titleColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(progressViewOffset, float)

@end