Skip to content

Commit

Permalink
feat(ios): add HippyFontChangeTriggerNotification for native font update
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwcg committed Jul 18, 2024
1 parent 4cd995d commit b07a29d
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 116 deletions.
10 changes: 6 additions & 4 deletions ios/sdk/base/HippyFont.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@
variant:(NSArray<NSString *> *)variant
scaleMultiplier:(CGFloat)scaleMultiplier;

+ (UIFont *)updateFont:(UIFont *)font withFamily:(NSString *)family;
+ (UIFont *)updateFont:(UIFont *)font withSize:(NSNumber *)size;
+ (UIFont *)updateFont:(UIFont *)font withWeight:(NSString *)weight;
+ (UIFont *)updateFont:(UIFont *)font withStyle:(NSString *)style;
/// Get the
/// JS side usually pass a `fontName` instead of `fontFamily`
/// If not match, the original value is returned.
///
/// - Parameter fontFamily: NSString *
+ (NSString *)familyNameWithCSSNameMatching:(NSString *)fontName;

@end

Expand Down
24 changes: 10 additions & 14 deletions ios/sdk/base/HippyFont.mm
Original file line number Diff line number Diff line change
Expand Up @@ -307,20 +307,16 @@ + (UIFont *)updateFont:(UIFont *)font
return font;
}

+ (UIFont *)updateFont:(UIFont *)font withFamily:(NSString *)family {
return [self updateFont:font withFamily:family size:nil weight:nil style:nil variant:nil scaleMultiplier:1];
}

+ (UIFont *)updateFont:(UIFont *)font withSize:(NSNumber *)size {
return [self updateFont:font withFamily:nil size:size weight:nil style:nil variant:nil scaleMultiplier:1];
}

+ (UIFont *)updateFont:(UIFont *)font withWeight:(NSString *)weight {
return [self updateFont:font withFamily:nil size:nil weight:weight style:nil variant:nil scaleMultiplier:1];
}

+ (UIFont *)updateFont:(UIFont *)font withStyle:(NSString *)style {
return [self updateFont:font withFamily:nil size:nil weight:nil style:style variant:nil scaleMultiplier:1];
+ (NSString *)familyNameWithCSSNameMatching:(NSString *)fontName {
NSString *familyName = fontName;
if (fontName && ![[UIFont familyNames] containsObject:fontName]) {
// Not a real FamilyName
// Using CSS name matching semantics.
// fontSize here is just a placeholder for getting font.
UIFont *cssFont = [UIFont fontWithName:fontName size:14.0];
familyName = cssFont.familyName;
}
return familyName;
}

@end
12 changes: 0 additions & 12 deletions ios/sdk/base/HippyRootView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,6 @@ - (NSNumber *)allocateRootTag

@implementation HippyRootContentView {
__weak HippyBridge *_bridge;
UIColor *_backgroundColor;
}

- (instancetype)initWithFrame:(CGRect)frame
Expand Down Expand Up @@ -484,17 +483,6 @@ - (void)setFrame:(CGRect)frame {
}
}

- (void)setBackgroundColor:(UIColor *)backgroundColor {
_backgroundColor = backgroundColor;
if (self.hippyTag && _bridge.isValid) {
[_bridge.uiManager setBackgroundColor:backgroundColor forView:self];
}
}

- (UIColor *)backgroundColor {
return _backgroundColor;
}

- (void)invalidate {
if (self.userInteractionEnabled) {
self.userInteractionEnabled = NO;
Expand Down
10 changes: 10 additions & 0 deletions ios/sdk/component/textinput/HippyBaseTextInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
#import "HippyView.h"

@interface HippyBaseTextInput : HippyView

/// Font property - FontSize
@property (nonatomic, strong) NSNumber *fontSize;
/// Font property - FontWeight
@property (nonatomic, strong) NSString *fontWeight;
/// Font property - FontStyle
@property (nonatomic, strong) NSString *fontStyle;
/// Font property - FontFamily
@property (nonatomic, strong) NSString *fontFamily;

@property (nonatomic, strong) UIFont *font;
@property (nonatomic, assign) UIEdgeInsets contentInset;
@property (nonatomic, copy) NSString *value;
Expand Down
54 changes: 54 additions & 0 deletions ios/sdk/component/textinput/HippyBaseTextInput.m
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

#import "HippyBaseTextInput.h"
#import "HippyFont.h"

@implementation HippyBaseTextInput
- (void)focus {
Expand All @@ -42,4 +43,57 @@ - (void)keyboardHeightChanged:(NSNotification *)aNotification {
// base method, should be override
}


#pragma mark - Hippy Update Callback

- (void)hippyBridgeDidFinishTransaction {
// Use this opportunity to update font if needed.
[self layoutIfNeeded];
}

- (void)layoutSubviews {
[super layoutSubviews];
[self rebuildAndUpdateFont];
}


#pragma mark - Font Related

- (void)setFontSize:(NSNumber *)fontSize {
_fontSize = fontSize;
[self setNeedsLayout];
}

- (void)setFontStyle:(NSString *)fontStyle {
_fontStyle = fontStyle;
[self setNeedsLayout];
}

- (void)setFontWeight:(NSString *)fontWeight {
_fontWeight = fontWeight;
[self setNeedsLayout];
}

- (void)setFontFamily:(NSString *)fontFamily {
_fontFamily = fontFamily;
[self setNeedsLayout];
}

- (void)rebuildAndUpdateFont {
// Convert fontName to fontFamily if needed
CGFloat scaleMultiplier = 1.0; // scale not supported
NSString *familyName = [HippyFont familyNameWithCSSNameMatching:self.fontFamily];
UIFont *font = [HippyFont updateFont:self.font
withFamily:familyName
size:self.fontSize
weight:self.fontWeight
style:self.fontStyle
variant:nil
scaleMultiplier:scaleMultiplier];
if (self.font != font) {
self.font = font;
}
}


@end
11 changes: 9 additions & 2 deletions ios/sdk/component/textinput/HippyShadowTextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,20 @@
@property (nonatomic, copy) NSString *text;
@property (nonatomic, copy) NSString *placeholder;

@property (nonatomic, strong) UIFont *font;

/// ParagraphStyles - lineHeight
@property (nonatomic, strong) NSNumber *lineHeight;
/// ParagraphStyles - lineSpacing
@property (nonatomic, strong) NSNumber *lineSpacing;
/// ParagraphStyles - lineHeightMultiple
@property (nonatomic, strong) NSNumber *lineHeightMultiple;

/// Font property - FontSize
@property (nonatomic, strong) NSNumber *fontSize;
/// Font property - FontWeight
@property (nonatomic, strong) NSString *fontWeight;
/// Font property - FontStyle
@property (nonatomic, strong) NSString *fontStyle;
/// Font property - FontFamily
@property (nonatomic, strong) NSString *fontFamily;

@end
76 changes: 76 additions & 0 deletions ios/sdk/component/textinput/HippyShadowTextView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,33 @@
#import "MTTLayout.h"
#import "x5LayoutUtil.h"
#import "HippyShadowView+MTTLayout.h"
#import "HippyFont.h"


@interface HippyShadowTextView ()

/// Cached font
@property (nonatomic, strong) UIFont *font;
/// Whether font needs to be updated.
@property (nonatomic, assign) BOOL isFontDirty;
/// Cached attributes
@property (nonatomic, strong) NSDictionary *dicAttributes;

/// rebuild and update the font property
- (void)rebuildAndUpdateFont;

@end

static MTTSize x5MeasureFunc(
MTTNodeRef node, float width, MeasureMode widthMeasureMode, __unused float height, __unused MeasureMode heightMeasureMode, void *layoutContext) {
HippyShadowTextView *shadowText = (__bridge HippyShadowTextView *)MTTNodeGetContext(node);
NSString *text = shadowText.text ?: shadowText.placeholder;
if (nil == shadowText.dicAttributes) {
if (shadowText.isFontDirty) {
[shadowText rebuildAndUpdateFont];
shadowText.isFontDirty = NO;
}
// Keep this historical code, default fontSize 16.
if (shadowText.font == nil) {
shadowText.font = [UIFont systemFontOfSize:16];
}
Expand Down Expand Up @@ -95,4 +112,63 @@ - (NSDictionary *)mergeProps:(NSDictionary *)props {
return newProps;
}

- (void)dirtyText {
[super dirtyText];
self.isFontDirty = YES;
self.dicAttributes = nil;
}

- (void)collectUpdatedProperties:(NSMutableSet<HippyApplierBlock> *)applierBlocks
virtualApplierBlocks:(NSMutableSet<HippyApplierVirtualBlock> *)virtualApplierBlocks
parentProperties:(NSDictionary<NSString *,id> *)parentProperties {
[super collectUpdatedProperties:applierBlocks
virtualApplierBlocks:virtualApplierBlocks
parentProperties:parentProperties];

// Set needs layout for font change event, etc.
NSNumber *currentTag = self.hippyTag;
[applierBlocks addObject:^(NSDictionary<NSNumber *, UIView *> *viewRegistry){
UIView *view = viewRegistry[currentTag];
[view setNeedsLayout];
}];
}


#pragma mark - Font Related

- (void)setFontSize:(NSNumber *)fontSize {
_fontSize = fontSize;
self.isFontDirty = YES;
}

- (void)setFontStyle:(NSString *)fontStyle {
_fontStyle = fontStyle;
self.isFontDirty = YES;
}

- (void)setFontWeight:(NSString *)fontWeight {
_fontWeight = fontWeight;
self.isFontDirty = YES;
}

- (void)setFontFamily:(NSString *)fontFamily {
_fontFamily = fontFamily;
self.isFontDirty = YES;
}

- (void)rebuildAndUpdateFont {
// Convert fontName to fontFamily if needed
NSString *familyName = [HippyFont familyNameWithCSSNameMatching:self.fontFamily];
UIFont *font = [HippyFont updateFont:self.font
withFamily:familyName
size:self.fontSize
weight:self.fontWeight
style:self.fontStyle
variant:nil
scaleMultiplier:1.0];
if (self.font != font) {
self.font = font;
}
}

@end
66 changes: 9 additions & 57 deletions ios/sdk/component/textinput/HippyTextViewManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ - (HippyShadowView *)shadowView {
HIPPY_EXPORT_SHADOW_PROPERTY(lineSpacing, NSNumber)
HIPPY_EXPORT_SHADOW_PROPERTY(lineHeightMultiple, NSNumber)

HIPPY_EXPORT_SHADOW_PROPERTY(fontSize, NSNumber)
HIPPY_EXPORT_SHADOW_PROPERTY(fontWeight, NSString)
HIPPY_EXPORT_SHADOW_PROPERTY(fontStyle, NSString)
HIPPY_EXPORT_SHADOW_PROPERTY(fontFamily, NSString)

HIPPY_EXPORT_VIEW_PROPERTY(lineHeight, NSNumber)
HIPPY_EXPORT_VIEW_PROPERTY(lineSpacing, NSNumber)
HIPPY_EXPORT_VIEW_PROPERTY(lineHeightMultiple, NSNumber)
Expand Down Expand Up @@ -195,44 +200,10 @@ - (HippyShadowView *)shadowView {
HIPPY_EXPORT_VIEW_PROPERTY(selection, HippyTextSelection)
HIPPY_EXPORT_VIEW_PROPERTY(text, NSString)

HIPPY_CUSTOM_SHADOW_PROPERTY(fontSize, NSNumber, HippyShadowTextView) {
view.font = [HippyFont updateFont:view.font withSize:json];
}

HIPPY_CUSTOM_SHADOW_PROPERTY(fontWeight, NSString, HippyShadowTextView) {
view.font = [HippyFont updateFont:view.font withWeight:json];
}

HIPPY_CUSTOM_SHADOW_PROPERTY(fontStyle, NSString, HippyShadowTextView) {
view.font = [HippyFont updateFont:view.font withStyle:json]; // defaults to normal
}

HIPPY_CUSTOM_SHADOW_PROPERTY(fontFamily, NSString, HippyShadowTextView) {
// Convert fontName to fontFamily if needed
NSString *familyName = [self familyNameWithCSSNameMatching:json];
view.font = [HippyFont updateFont:view.font withFamily:familyName];
}

HIPPY_CUSTOM_VIEW_PROPERTY(fontSize, NSNumber, HippyBaseTextInput) {
UIFont *theFont = [HippyFont updateFont:view.font withSize:json ?: @(defaultView.font.pointSize)];
view.font = theFont;
}

HIPPY_CUSTOM_VIEW_PROPERTY(fontWeight, NSString, __unused HippyBaseTextInput) {
UIFont *theFont = [HippyFont updateFont:view.font withWeight:json]; // defaults to normal
view.font = theFont;
}

HIPPY_CUSTOM_VIEW_PROPERTY(fontStyle, NSString, __unused HippyBaseTextInput) {
UIFont *theFont = [HippyFont updateFont:view.font withStyle:json];
view.font = theFont; // defaults to normal
}

HIPPY_CUSTOM_VIEW_PROPERTY(fontFamily, NSString, HippyBaseTextInput) {
// Convert fontName to fontFamily if needed
NSString *familyName = [self familyNameWithCSSNameMatching:json];
view.font = [HippyFont updateFont:view.font withFamily:familyName ?: defaultView.font.familyName];
}
HIPPY_EXPORT_VIEW_PROPERTY(fontSize, NSNumber)
HIPPY_EXPORT_VIEW_PROPERTY(fontWeight, NSString)
HIPPY_EXPORT_VIEW_PROPERTY(fontStyle, NSString)
HIPPY_EXPORT_VIEW_PROPERTY(fontFamily, NSString)

- (HippyViewManagerUIBlock)uiBlockToAmendWithShadowView:(HippyShadowView *)shadowView {
NSNumber *hippyTag = shadowView.hippyTag;
Expand All @@ -242,23 +213,4 @@ - (HippyViewManagerUIBlock)uiBlockToAmendWithShadowView:(HippyShadowView *)shado
};
}


#pragma mark - Private

/// Get the
/// JS side usually pass a `fontName` instead of `fontFamily`
/// - Parameter json: id
- (NSString *)familyNameWithCSSNameMatching:(id)json {
NSString *familyName = json;
if (json && ![[UIFont familyNames] containsObject:json]) {
// Not a real FamilyName
// Using CSS name matching semantics.
// fontSize here is just a placeholder for getting font.
UIFont *cssFont = [UIFont fontWithName:json size:14.0];
familyName = cssFont.familyName;
}
return familyName;
}


@end
19 changes: 12 additions & 7 deletions ios/sdk/module/uimanager/HippyUIManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ HIPPY_EXTERN NSString *const HippyUIManagerRootViewKey;
*/
HIPPY_EXTERN NSString *const HippyUIManagerDidEndBatchNotification;

/**
* This notification can be sent when the font is registered or modified on the native side
* and hippy needs to be refreshed.
*
* `notification.object` can carry rootTag to filter the RootView that needs to be refreshed.
* Default value nil indicating that a refresh is required.
*/
HIPPY_EXTERN NSString *const HippyFontChangeTriggerNotification;


#pragma mark -

@protocol HippyScrollableProtocol;

/**
Expand Down Expand Up @@ -110,13 +122,6 @@ HIPPY_EXTERN NSString *const HippyUIManagerDidEndBatchNotification;
*/
- (void)setIntrinsicContentSize:(CGSize)size forView:(UIView *)view;

/**
* Update the background color of a view. The source of truth for
* backgroundColor is the shadow view, so if to update backgroundColor from
* native code you will need to call this method.
*/
- (void)setBackgroundColor:(UIColor *)color forView:(UIView *)view;

/**
* Schedule a block to be executed on the UI thread. Useful if you need to execute
* view logic after all currently queued view updates have completed.
Expand Down
Loading

0 comments on commit b07a29d

Please sign in to comment.