#import "PLYScrollView.h"
@implementation PLYScrollView
- (id)init {
if ((self = [super init])) {
self.alwaysBounceVertical = YES;
self.opaque = NO;
if (@available(iOS 11.0, *)) {
self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
if (@available(iOS 13.0, *)) {
self.automaticallyAdjustsScrollIndicatorInsets = NO;
}
self.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
self.delaysContentTouches = NO;
}
return self;
}
- (void)updateLayout {
if (self.layout == nil)
return;
CGRect oldFrame = self.frame;
CGRect newFrame = [self.layout fetch];
if (CGRectEqualToRect(oldFrame, newFrame))
return;
self.frame = newFrame;
for (UIView *view in self.subviews)
[view setNeedsLayout];
}
- (void)updateContentLayout {
CGSize oldSize = self.contentSize;
CGSize newSize = [self.contentLayout fetch].size;
if (CGSizeEqualToSize(oldSize, newSize))
return;
self.contentSize = newSize;
}
- (void)layoutSubviews {
[super layoutSubviews];
[self updateLayout];
[self updateContentLayout];
}
- (void)setOpaqueBackgroundColor:(UIColor *)color {
_opaqueBackgroundColor = color;
[self setNeedsDisplay];
}
- (CGPoint)resolvePoint:(PLYPoint)point {
CGPoint result = CGPointZero;
if (point.x.kind == PLYDimensionKindPixels)
result.x = point.x.value;
else if (point.x.kind == PLYDimensionKindPercentage)
result.x = point.x.value * self.bounds.size.width;
if (point.y.kind == PLYDimensionKindPixels)
result.y = point.y.value;
else if (point.y.kind == PLYDimensionKindPercentage)
result.y = point.y.value * self.bounds.size.height;
return result;
}
- (void)drawRect:(CGRect)dirtyRect {
const CGFloat kappa = 4 * (sqrt(2.0) - 1.0) / 3.0;
CGPoint tl = [self resolvePoint:self.cornerRadii.topLeft];
CGPoint tr = [self resolvePoint:self.cornerRadii.topRight];
CGPoint br = [self resolvePoint:self.cornerRadii.bottomRight];
CGPoint bl = [self resolvePoint:self.cornerRadii.bottomLeft];
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(tl.x, 0.0)];
[path addLineToPoint:CGPointMake(self.bounds.size.width - tr.x, 0.0)];
[path addCurveToPoint:CGPointMake(self.bounds.size.width, tr.y)
controlPoint1:CGPointMake(self.bounds.size.width - tr.x + tr.x * kappa, 0.0)
controlPoint2:CGPointMake(self.bounds.size.width, tr.y - tr.y * kappa)];
[path addLineToPoint:CGPointMake(self.bounds.size.width, self.bounds.size.height - br.y)];
[path addCurveToPoint:CGPointMake(self.bounds.size.width - br.x, self.bounds.size.height)
controlPoint1:CGPointMake(self.bounds.size.width, self.bounds.size.height - br.y + br.y * kappa)
controlPoint2:CGPointMake(self.bounds.size.width - br.x + br.x * kappa, self.bounds.size.height)];
[path addLineToPoint:CGPointMake(bl.x, self.bounds.size.height)];
[path addCurveToPoint:CGPointMake(0.0, self.bounds.size.height - bl.y)
controlPoint1:CGPointMake(bl.x - bl.x * kappa, self.bounds.size.height)
controlPoint2:CGPointMake(0.0, self.bounds.size.height - bl.y + bl.y * kappa)];
[path addLineToPoint:CGPointMake(0.0, tl.y)];
[path addCurveToPoint:CGPointMake(tl.x, 0.0)
controlPoint1:CGPointMake(0.0, tl.y - tl.y * kappa)
controlPoint2:CGPointMake(tl.x - tl.x * kappa, 0.0)];
[path closePath];
[self.opaqueBackgroundColor setFill];
[path fill];
}
@end