From 1303a46148d0529899d4d4a39223effe2db718ce Mon Sep 17 00:00:00 2001 From: Shahen Hovhannisyan Date: Thu, 8 Jun 2017 19:55:23 +0400 Subject: [PATCH] feat(Trimmer iOS): Added trackerHandle BREAKING CHANGE changed some styles and dimensions --- .../ICGVideoTrimmer/ICGVideoTrimmerView.h | 5 ++ .../ICGVideoTrimmer/ICGVideoTrimmerView.m | 61 ++++++++++--- .../RNTrimmerView/RNTrimmerView.h | 1 + .../RNTrimmerView/RNTrimmerView.swift | 88 +++++++++++++------ .../RNTrimmerView/RNTrimmerViewBridge.m | 2 + lib/Trimmer/Trimmer.ios.js | 10 ++- 6 files changed, 128 insertions(+), 39 deletions(-) diff --git a/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.h b/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.h index 3c49a9ed..df92771e 100755 --- a/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.h +++ b/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.h @@ -33,6 +33,11 @@ NS_ASSUME_NONNULL_BEGIN // Customize color for tracker @property (assign, nonatomic) UIColor *trackerColor; +// Customize color for tracker handle +@property (assign, nonatomic) UIColor *trackerHandleColor; + +@property (assign, nonatomic) Boolean showTrackerHandle; + // Custom image for the left thumb @property (strong, nonatomic, nullable) UIImage *leftThumbImage; diff --git a/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.m b/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.m index 7c41031b..f952d485 100755 --- a/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.m +++ b/ios/RNVideoProcessing/RNTrimmerView/ICGVideoTrimmer/ICGVideoTrimmerView.m @@ -23,6 +23,8 @@ @interface ICGVideoTrimmerView() @property (strong, nonatomic) ICGThumbView *rightThumbView; @property (strong, nonatomic) UIView *trackerView; +@property (strong, nonatomic) UIView *tracker; +@property (strong, nonatomic) UIView *trackerHandle; @property (strong, nonatomic) UIView *topBorder; @property (strong, nonatomic) UIView *bottomBorder; @property (strong, nonatomic) UIPanGestureRecognizer *panGestureRecognizer; @@ -31,6 +33,7 @@ @interface ICGVideoTrimmerView() @property (nonatomic) CGFloat endTime; @property (nonatomic) CGFloat widthPerSecond; +@property (nonatomic) int trackerHandleHeight; @property (nonatomic) CGPoint leftStartPoint; @property (nonatomic) CGPoint rightStartPoint; @@ -91,6 +94,16 @@ - (UIColor *)trackerColor return _trackerColor ?: [UIColor whiteColor]; } +- (UIColor *) trackerHandleColor +{ + return _trackerHandleColor ?: [UIColor whiteColor]; +} + +- (Boolean) showTrackerHandle +{ + return _showTrackerHandle ?: NO; +} + - (CGFloat)borderWidth { return _borderWidth ?: 1; @@ -103,13 +116,15 @@ - (CGFloat)thumbWidth - (void)resetSubviews { - self.clipsToBounds = YES; + // self.clipsToBounds = YES; + + self.trackerHandleHeight = 20; - [self setBackgroundColor:[UIColor blackColor]]; + [self setBackgroundColor:[UIColor clearColor]]; [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; - self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame))]; + self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame) - self.trackerHandleHeight)]; [self.scrollView setBounces:NO]; [self.scrollView setScrollEnabled:NO]; [self addSubview:self.scrollView]; @@ -122,7 +137,7 @@ - (void)resetSubviews CGFloat ratio = self.showsRulerView ? 0.7 : 1.0; self.frameView = [[UIView alloc] initWithFrame:CGRectMake(self.thumbWidth, 0, CGRectGetWidth(self.contentView.frame)-2*self.thumbWidth, CGRectGetHeight(self.contentView.frame)*ratio)]; - [self.frameView.layer setMasksToBounds:YES]; + //[self.frameView.layer setMasksToBounds:YES]; [self.contentView addSubview:self.frameView]; [self addFrames]; @@ -154,19 +169,38 @@ - (void)resetSubviews self.leftThumbView = [[ICGThumbView alloc] initWithFrame:leftThumbFrame color:self.themeColor right:NO]; } - self.trackerView = [[UIView alloc] initWithFrame:CGRectMake(self.thumbWidth, -5, 3, CGRectGetHeight(self.frameView.frame) + 20)]; - self.trackerView.backgroundColor = self.trackerColor; - self.trackerView.layer.masksToBounds = true; - self.trackerView.layer.cornerRadius = 2; + self.trackerView = [[UIView alloc] initWithFrame:CGRectMake(self.thumbWidth - self.trackerHandleHeight / 2, 0, 20, CGRectGetHeight(self.frameView.frame) + self.trackerHandleHeight)]; + self.tracker = [[UIView alloc] initWithFrame:CGRectMake(self.thumbWidth, 0, 3, CGRectGetHeight(self.frameView.frame))]; + self.trackerHandle = [[UIView alloc] initWithFrame:CGRectMake(1, CGRectGetHeight(self.frameView.frame), self.trackerHandleHeight, self.trackerHandleHeight)]; + + [self.trackerHandle.layer setMasksToBounds:YES]; + [self.contentView setUserInteractionEnabled:YES]; + + // self.trackerHandle.clipsToBounds = YES; + [self.trackerHandle.layer setCornerRadius:10]; + self.tracker.backgroundColor = self.trackerColor; + self.trackerHandle.backgroundColor = self.trackerHandleColor; + // self.trackerView.layer.masksToBounds = true; + self.tracker.layer.cornerRadius = 2; + + + [self.trackerView addSubview:self.tracker]; + if (self.showTrackerHandle) { + [self.trackerView addSubview: self.trackerHandle]; + } + [self.tracker setUserInteractionEnabled:YES]; [self.trackerView setUserInteractionEnabled:YES]; + [self.trackerHandle setUserInteractionEnabled:YES]; [self addSubview:self.trackerView]; self.panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleTrackerPan:)]; - [self.panGestureRecognizer locationInView:self.trackerView]; + [self.panGestureRecognizer locationInView: self.trackerView]; [self.trackerView addGestureRecognizer:self.panGestureRecognizer]; + // [self.trackerHandle addGestureRecognizer:self.panGestureRecognizer]; + [self.leftThumbView.layer setMasksToBounds:YES]; [self.leftOverlayView addSubview:self.leftThumbView]; @@ -203,14 +237,15 @@ - (void)updateBorderFrames [self.bottomBorder setFrame:CGRectMake(CGRectGetMaxX(self.leftOverlayView.frame), CGRectGetHeight(self.frameView.frame)-height, CGRectGetMinX(self.rightOverlayView.frame)-CGRectGetMaxX(self.leftOverlayView.frame), height)]; } -- (void)handleTrackerPan: (UISwipeGestureRecognizer *) recognizer { +- (void)handleTrackerPan: (UIGestureRecognizer *) recognizer { + NSLog(@"Test"); CGPoint point = [self.panGestureRecognizer locationInView:self.trackerView]; CGRect trackerFrame = self.trackerView.frame; - trackerFrame.origin.x += point.x; + trackerFrame.origin.x += point.x - self.trackerHandleHeight / 2; self.trackerView.frame = trackerFrame; - CGFloat time = (trackerFrame.origin.x - self.thumbWidth + self.scrollView.contentOffset.x) / self.widthPerSecond; + CGFloat time = (trackerFrame.origin.x - self.thumbWidth + self.scrollView.contentOffset.x + self.trackerHandleHeight) / self.widthPerSecond; [self.delegate trimmerView:self currentPosition:time ]; } @@ -294,7 +329,7 @@ - (void)seekToTime:(CGFloat) time CGFloat posToMove = time * self.widthPerSecond + self.thumbWidth - self.scrollView.contentOffset.x; CGRect trackerFrame = self.trackerView.frame; - trackerFrame.origin.x = posToMove; + trackerFrame.origin.x = posToMove - self.trackerHandleHeight / 2; self.trackerView.frame = trackerFrame; } diff --git a/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.h b/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.h index 95f1aab6..18615679 100644 --- a/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.h +++ b/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.h @@ -7,6 +7,7 @@ #define RNTrimmerView_h #import "ICGVideoTrimmer.h" +#import "React/RCTView.h" #import "React/RCTViewManager.h" #import "React/RCTConvert.h" #import "React/RCTBridge.h" diff --git a/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.swift b/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.swift index f8bc4a07..468f67b9 100644 --- a/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.swift +++ b/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerView.swift @@ -8,7 +8,7 @@ import AVKit @objc(RNTrimmerView) class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { - + var trimmerView: ICGVideoTrimmerView? var asset: AVAsset! var rect: CGRect = CGRect.zero @@ -20,27 +20,63 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { var _maxLength: CGFloat? = nil var _thumbWidth: CGFloat? = nil var _trackerColor: UIColor = UIColor.clear - + var _trackerHandleColor: UIColor = UIColor.clear + var _showTrackerHandle = false + var source: NSString? { set { setSource(source: newValue) } get { - + return nil } } - + + var showTrackerHandle: NSNumber? { + set { + if newValue == nil { + return + } + let _nVal = newValue! == 1 ? true : false + if _showTrackerHandle != _nVal { + print("CHANGED: showTrackerHandle \(newValue!)"); + _showTrackerHandle = _nVal + self.updateView() + } + } + get { + return nil + } + } + + var trackerHandleColor: NSString? { + set { + if newValue != nil { + let color = NumberFormatter().number(from: newValue! as String) + let formattedColor = RCTConvert.uiColor(color) + if formattedColor != nil { + print("CHANGED: trackerHandleColor: \(newValue!)") + self._trackerHandleColor = formattedColor! + self.updateView(); + } + } + } + get { + return nil + } + } + var height: NSNumber? { set { - self.rect.size.height = RCTConvert.cgFloat(newValue) + self.rect.size.height = RCTConvert.cgFloat(newValue) + 40 self.updateView() } get { return nil } } - + var width: NSNumber? { set { self.rect.size.width = RCTConvert.cgFloat(newValue) @@ -50,7 +86,7 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + var themeColor: NSString? { set { if newValue != nil { @@ -63,7 +99,7 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + var maxLength: NSNumber? { set { if newValue != nil { @@ -75,7 +111,7 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + var minLength: NSNumber? { set { if newValue != nil { @@ -87,7 +123,7 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + var thumbWidth: NSNumber? { set { if newValue != nil { @@ -99,7 +135,7 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + var currentTime: NSNumber? { set { print("CHANGED: [TrimmerView]: currentTime: \(newValue)") @@ -113,15 +149,13 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + var trackerColor: NSString? { set { if newValue == nil { return } - if self.trimmerView == nil { - return - } + print("CHANGED: trackerColor \(newValue!)") let color = NumberFormatter().number(from: newValue! as String) let formattedColor = RCTConvert.uiColor(color) if formattedColor != nil { @@ -133,14 +167,18 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { return nil } } - + func updateView() { self.frame = rect if trimmerView != nil { trimmerView!.frame = rect trimmerView!.themeColor = self.mThemeColor trimmerView!.trackerColor = self._trackerColor + trimmerView!.trackerHandleColor = self._trackerHandleColor + trimmerView!.showTrackerHandle = self._showTrackerHandle trimmerView!.maxLength = _maxLength == nil ? CGFloat(self.asset.duration.seconds) : _maxLength! + self.frame = CGRect(x: rect.origin.x, y: rect.origin.y, width: rect.size.width, height: rect.size.height + 20) + self.backgroundColor = UIColor.blue if _minLength != nil { trimmerView!.minLength = _minLength! } @@ -151,16 +189,16 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { // Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.updateTrimmer), userInfo: nil, repeats: false) } } - + func updateTrimmer() { self.trimmerView!.resetSubviews() } - + func setSource(source: NSString?) { if source != nil { let pathToSource = NSURL(string: source! as String) - self.asset = AVURLAsset(url: pathToSource as! URL, options: nil) - + self.asset = AVURLAsset(url: pathToSource! as URL, options: nil) + trimmerView = ICGVideoTrimmerView(frame: rect, asset: self.asset) trimmerView!.showsRulerView = false trimmerView!.hideTracker(false) @@ -170,27 +208,27 @@ class RNTrimmerView: RCTView, ICGVideoTrimmerDelegate { self.updateView() } } - + init(frame: CGRect, bridge: RCTBridge) { super.init(frame: frame) self.bridge = bridge } - + required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } - + func onTrimmerPositionChange(startTime: CGFloat, endTime: CGFloat) { if self.onChange != nil { let event = ["startTime": startTime, "endTime": endTime] self.onChange!(event) } } - + func trimmerView(_ trimmerView: ICGVideoTrimmerView, didChangeLeftPosition startTime: CGFloat, rightPosition endTime: CGFloat) { onTrimmerPositionChange(startTime: startTime, endTime: endTime) } - + public func trimmerView(_ trimmerView: ICGVideoTrimmerView, currentPosition currentTime: CGFloat) { print("current", currentTime) if onTrackerMove == nil { diff --git a/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerViewBridge.m b/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerViewBridge.m index e0540f6e..ca448170 100644 --- a/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerViewBridge.m +++ b/ios/RNVideoProcessing/RNTrimmerView/RNTrimmerViewBridge.m @@ -21,5 +21,7 @@ @interface RCT_EXTERN_MODULE(RNTrimmerViewManager, RCTViewManager) RCT_EXPORT_VIEW_PROPERTY(currentTime, NSNumber) RCT_EXPORT_VIEW_PROPERTY(trackerColor, NSString) RCT_EXPORT_VIEW_PROPERTY(thumbWidth, NSNumber) +RCT_EXPORT_VIEW_PROPERTY(showTrackerHandle, NSNumber) +RCT_EXPORT_VIEW_PROPERTY(trackerHandleColor, NSString) @end diff --git a/lib/Trimmer/Trimmer.ios.js b/lib/Trimmer/Trimmer.ios.js index ec332ac8..cf5c4c7e 100644 --- a/lib/Trimmer/Trimmer.ios.js +++ b/lib/Trimmer/Trimmer.ios.js @@ -8,6 +8,8 @@ export class Trimmer extends Component { source: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, width: PropTypes.number, height: PropTypes.number, + showTrackerHandle: PropTypes.bool, + trackerHandleColor: PropTypes.string, themeColor: PropTypes.string, onChange: PropTypes.func, onTrackerMove: PropTypes.func, @@ -21,7 +23,9 @@ export class Trimmer extends Component { static defaultProps = { themeColor: 'gray', - trackerColor: 'black' + trackerColor: 'black', + trackerHandleColor: 'gray', + showTrackerHandle: false }; constructor(...args) { @@ -58,6 +62,8 @@ export class Trimmer extends Component { trackerColor, thumbWidth, borderWidth, + showTrackerHandle, + trackerHandleColor } = this.props; const actualSource = getActualSource(source); return ( @@ -68,6 +74,8 @@ export class Trimmer extends Component { currentTime={currentTime} themeColor={processColor(themeColor).toString()} trackerColor={processColor(trackerColor).toString()} + showTrackerHandle={showTrackerHandle} + trackerHandleColor={processColor(trackerHandleColor).toString()} onTrackerMove={this._handleTrackerMove} pointerEvents={'box-none'} onChange={this._onChange}