UIScrollViews will now report 'scroll' events and the background in ios will adjust added layers (#4762)

This commit is contained in:
Panayot Cankov
2017-08-29 10:25:45 +03:00
committed by SvetoslavTsenov
parent 3fd65cce9f
commit 12c0199fb5
18 changed files with 413 additions and 22 deletions

View File

@@ -437,7 +437,10 @@ export class View extends ViewCommon {
_setNativeClipToBounds() {
let backgroundInternal = this.style.backgroundInternal;
this.nativeViewProtected.clipsToBounds = backgroundInternal.hasBorderWidth() || backgroundInternal.hasBorderRadius();
this.nativeViewProtected.clipsToBounds =
this.nativeViewProtected instanceof UIScrollView ||
backgroundInternal.hasBorderWidth() ||
backgroundInternal.hasBorderRadius();
}
}
View.prototype._nativeBackgroundState = "unset";

View File

@@ -1,4 +1,5 @@
import { ItemEventData } from ".";
import { ScrollEventData } from "../scroll-view";
import { ItemEventData } from ".";
import {
ListViewBase, View, KeyedTemplate, Length, Observable, Color,
separatorColorProperty, itemTemplatesProperty, layout, EventData

View File

@@ -17,7 +17,7 @@ class UIScrollViewDelegateImpl extends NSObject implements UIScrollViewDelegate
if (owner) {
owner.notify(<ScrollEventData>{
object: owner,
eventName: ScrollViewBase.scrollEvent,
eventName: "scroll",
scrollX: owner.horizontalOffset,
scrollY: owner.verticalOffset
});

View File

@@ -1,3 +1,5 @@
import { ScrollEventData } from "../scroll-view";
import { Background as BackgroundDefinition } from "./background";
import { View, Point } from "../core/view";
import { Color } from "../../color";
@@ -10,15 +12,15 @@ export * from "./background-common";
interface NativeView extends UIView {
hasNonUniformBorder: boolean;
borderLayer: CAShapeLayer;
borderLayer: CALayer;
hasBorderMask: boolean;
borderOriginalMask: CALayer;
topBorderLayer: CAShapeLayer;
rightBorderLayer: CAShapeLayer;
bottomBorderLayer: CAShapeLayer;
leftBorderLayer: CAShapeLayer;
topBorderLayer: CALayer;
rightBorderLayer: CALayer;
bottomBorderLayer: CALayer;
leftBorderLayer: CALayer;
}
interface Rect {
@@ -37,11 +39,15 @@ export module ios {
const nativeView = <NativeView>view.nativeViewProtected;
if (nativeView.hasNonUniformBorder) {
unsubscribeFromScrollNotifications(view);
clearNonUniformBorders(nativeView);
}
if (background.hasUniformBorderColor() && background.hasBorderRadius()) {
const hasNonUniformBorderWidths = background.hasBorderWidth() && !background.hasUniformBorder();
const hasNonUniformBorderRadiuses = background.hasBorderRadius() && !background.hasUniformBorderRadius();
if (background.hasUniformBorderColor() && (hasNonUniformBorderWidths || hasNonUniformBorderRadiuses)) {
drawUniformColorNonUniformBorders(nativeView, background);
subscribeForScrollNotifications(view);
} else if (background.hasUniformBorder()) {
const layer = nativeView.layer;
const borderColor = background.getUniformBorderColor();
@@ -52,6 +58,7 @@ export module ios {
layer.cornerRadius = Math.min(Math.min(renderSize.width / 2, renderSize.height / 2), cornerRadius);
} else {
drawNoRadiusNonUniformBorders(nativeView, background);
subscribeForScrollNotifications(view);
}
// Clip-path should be called after borders are applied.
@@ -69,6 +76,42 @@ export module ios {
}
}
function onScroll(this: void, args: ScrollEventData): void {
const view = <View>args.object;
const nativeView = view.nativeViewProtected;
if (nativeView instanceof UIScrollView) {
adjustLayersForScrollView(<any>nativeView);
}
}
function adjustLayersForScrollView(nativeView: UIScrollView & NativeView) {
const layer = nativeView.borderLayer;
if (layer instanceof CALayer) {
// Compensates with transition for the background layers for scrolling in ScrollView based controls.
CATransaction.begin();
CATransaction.setValueForKey(kCFBooleanTrue, kCATransactionDisableActions);
const offset = nativeView.contentOffset;
const transform = { a: 1, b: 0, c: 0, d: 1, tx: offset.x, ty: offset.y };
layer.setAffineTransform(transform);
if (nativeView.layer.mask) {
nativeView.layer.mask.setAffineTransform(transform);
}
CATransaction.commit();
}
}
function unsubscribeFromScrollNotifications(view: View) {
if (view.nativeViewProtected instanceof UIScrollView) {
view.off("scroll", onScroll);
}
}
function subscribeForScrollNotifications(view: View) {
if (view.nativeViewProtected instanceof UIScrollView) {
view.on("scroll", onScroll);
adjustLayersForScrollView(<any>view.nativeViewProtected);
}
}
function clearNonUniformBorders(nativeView: NativeView): void {
if (nativeView.borderLayer) {
nativeView.borderLayer.removeFromSuperlayer();
@@ -507,12 +550,15 @@ function drawUniformColorNonUniformBorders(nativeView: NativeView, background: B
}
function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: BackgroundDefinition) {
const layer = nativeView.layer;
layer.borderColor = undefined;
layer.borderWidth = 0;
layer.cornerRadius = 0;
const borderLayer = CALayer.layer();
nativeView.layer.addSublayer(borderLayer);
nativeView.borderLayer = borderLayer;
const layerBounds = layer.bounds;
borderLayer.borderColor = undefined;
borderLayer.borderWidth = 0;
borderLayer.cornerRadius = 0;
const layerBounds = nativeView.layer.bounds;
const layerOrigin = layerBounds.origin;
const layerSize = layerBounds.size;
@@ -555,7 +601,7 @@ function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: Backg
topBorderLayer.fillColor = background.borderTopColor.ios.CGColor;
topBorderLayer.path = topBorderPath;
layer.addSublayer(topBorderLayer);
borderLayer.addSublayer(topBorderLayer);
nativeView.topBorderLayer = topBorderLayer;
hasNonUniformBorder = true;
}
@@ -573,7 +619,7 @@ function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: Backg
rightBorderLayer.fillColor = background.borderRightColor.ios.CGColor;
rightBorderLayer.path = rightBorderPath;
layer.addSublayer(rightBorderLayer);
borderLayer.addSublayer(rightBorderLayer);
nativeView.rightBorderLayer = rightBorderLayer;
hasNonUniformBorder = true;
}
@@ -591,7 +637,7 @@ function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: Backg
bottomBorderLayer.fillColor = background.borderBottomColor.ios.CGColor;
bottomBorderLayer.path = bottomBorderPath;
layer.addSublayer(bottomBorderLayer);
borderLayer.addSublayer(bottomBorderLayer);
nativeView.bottomBorderLayer = bottomBorderLayer;
hasNonUniformBorder = true;
}
@@ -609,7 +655,7 @@ function drawNoRadiusNonUniformBorders(nativeView: NativeView, background: Backg
leftBorderLayer.fillColor = background.borderLeftColor.ios.CGColor;
leftBorderLayer.path = leftBorderPath;
layer.addSublayer(leftBorderLayer);
borderLayer.addSublayer(leftBorderLayer);
nativeView.leftBorderLayer = leftBorderLayer;
hasNonUniformBorder = true;
}

View File

@@ -1,4 +1,5 @@
import { TextView as TextViewDefinition } from ".";
import { ScrollEventData } from "../scroll-view";
import { TextView as TextViewDefinition } from ".";
import {
EditableTextBase, editableProperty, hintProperty, textProperty, colorProperty, placeholderColorProperty,
borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty,
@@ -9,8 +10,8 @@ import { profile } from "../../profiling";
export * from "../editable-text-base";
class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
public static ObjCProtocols = [UITextViewDelegate];
class UITextViewDelegateImpl extends NSObject implements UIScrollViewDelegate, UITextViewDelegate {
public static ObjCProtocols = [UITextViewDelegate, UIScrollViewDelegate];
private _owner: WeakRef<TextView>;
@@ -76,6 +77,19 @@ class UITextViewDelegateImpl extends NSObject implements UITextViewDelegate {
return true;
}
public scrollViewDidScroll(sv: UIScrollView): void {
const owner = this._owner.get();
if (owner) {
const contentOffset = owner.nativeViewProtected.contentOffset;
owner.notify(<ScrollEventData>{
object: owner,
eventName: "scroll",
scrollX: contentOffset.x,
scrollY: contentOffset.y
});
}
}
}
export class TextView extends EditableTextBase implements TextViewDefinition {