如何在 nativescript angular 中从本机 ios 访问 UIScrollview 委托?
How to access UIScrollview delegates from native ios in nativescript angular?
我正在使用 nativescript android 和 ios 应用程序工作 angular application.i 想访问 ios 的滚动视图委托,我被访问了来自本机 ios 的滚动视图委托在 code.but 之后不起作用:
我的 scrollview 委托实现 class:
// import {Injectable, EventEmitter,Output} from "@angular/core";
@ObjCClass(UIScrollViewDelegate)
export class FoodScrollDelegate extends NSObject implements UIScrollViewDelegate
{
public static ObjCProtocols = [UIScrollViewDelegate];
// @Output() yvalue:EventEmitter<any>=new EventEmitter();
private _originalDelegate:UIScrollViewDelegate;
public getY:Number=0;
constructor()
{
super();
}
public static initWithOriginalDelegate(originalDelegate:UIScrollViewDelegate):FoodScrollDelegate{
console.log("Called Method");
let delegate=<FoodScrollDelegate>FoodScrollDelegate.new();
delegate._originalDelegate=originalDelegate;
return delegate;
}
}
我已经像这样设置滚动视图委托:
onScrollLoaded(args)
{
var subscroll=args.object;
var uiscrollview=subscroll.ios;
let tf=<any>this.subMenuScroll;
var newweakref=new WeakRef(uiscrollview);
const newDelegate=FoodScrollDelegate.initWithOriginalDelegate(tf._delegate);
console.log("PrintDelegate",+newDelegate);
uiscrollview.delegate=newDelegate;
}
我的 MenuComponet class 像这样:
import { Component, OnInit, AfterViewInit,ViewChild, ElementRef} from "@angular/core";
import {Page, borderTopRightRadiusProperty} from "ui/page";
import { isIOS, isAndroid } from 'tns-core-modules/platform';
import { RadListView, ListViewEventData } from "nativescript-ui-listview";
import { RestaurentMenuModel,RestaurentSubMenuModel } from "~/app/models/restaurant";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { run } from "tns-core-modules/application/application";
import { ScrollEventData, ScrollView } from "tns-core-modules/ui/scroll-view/scroll-view";
import { RouterExtensions } from "nativescript-angular/router";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
import { Label } from "tns-core-modules/ui/label/label";
import { analyzeAndValidateNgModules } from "@angular/compiler";
import * as utils from "tns-core-modules/utils/utils";
import { setTimeout } from "tns-core-modules/timer";
import { EventData } from "data/observable";
import { FoodScrollDelegate } from "~/app/Utils/scroll_delegate";
declare var UITableViewCellSelectionStyle;
declare var UIView, NSMutableArray, NSIndexPath;
//declare var setShowsHorizontalScrollIndicator;
@Component({
selector:"restaurant_menu",
moduleId:module.id,
templateUrl:"./restaurant_menu.component.html",
styleUrls:["./restaurant_menu.component.css"],
})
export class RestaurantMenu implements OnInit
{
//public cartCount:Number=1;
@ViewChild("ScrollList") scrollList:ElementRef;
@ViewChild("categoryList") categoryList:ElementRef;
public AllMenuList:any;
public cartTotal:any=0;
public cartItem:any=0;
public isCartVisible=false;
incrementItem:any=0;
decrementItem:any=0;
categoryContainer:Label;
subMenuContainers:StackLayout;
offsetValue:any=0;
dummyStatus:any=0;
horizontalOffsetvalue:any=0;
lengthHorizontaloffsetLength:any=0;
public selectedIndex:Number=0;
public scrollEnabled:Boolean=false;
lastItemY:Number=0;
subMenuScroll:ScrollView;
foodScrollDelegate:FoodScrollDelegate;
_delegate:any;
constructor(private page:Page,public routerExtension:RouterExtensions)
{
}
ngOnInit()
{
this.subMenuScroll=this.page.getViewById("subMenuScroll");
//this.subMenuScroll.ios.delegate=FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
//console.log("PrintDelegate"+this.foodScrollDelegate.scrollViewDidEndDraggingWillDecelerate);
// this.foodScrollDelegate=new FoodScrollDelegate();
// this.foodScrollDelegate.yvalue.subscribe(yvalue=>{
// console.log("TheYYValue"+yvalue);
// });
}
public scrollViewDidEndDraggingWillDecelerate?(scrollView: UIScrollView, decelerate: boolean): void {
console.log("WillScrollEnd"+" "+decelerate);
}
public scrollViewDidScroll?(scrollView: UIScrollView): void {
this.getY=scrollView.contentOffset.y;
console.log("Yposition"+this.getY);
//this.yvalue.emit(this.getY);
}
onLoaded(event)
{
const scrollview = event.object;
if (scrollview.ios) {
scrollview.ios.showsHorizontalScrollIndicator = false;
}
else
{
scrollview.android.setHorizontalScrollBarEnabled(false);
}
}
onNavBtnTap()
{
this.routerExtension.backToPreviousPage();
}
}
在 i 中实现了委托 methods.but 它正在工作
ObjCClass
是 ObjCProtocols
的替代语法。您可能不需要两者都做。
加载事件后附加默认委托,因此您的委托可能会再次被覆盖。您将必须扩展 ScrollView 并覆盖 attachNative
方法。
class MyScrollView extends ScrollView {
protected attachNative() {
(<any>ScrollView.prototype).attachNative.call(this);
if (isIOS) {
(<any>this)._delegate = FoodScrollDelegate.initWithOriginalDelegate((<any>this)._delegate);
this.nativeViewProtected.delegate = (<any>this)._delegate;
}
}
}
注册这个 MyScrollView
,
registerElement("MyScrollView", () => MyScrollView);
现在您应该可以在 HTML 中使用 MyScrollView
而不是 ScrollView
,这将覆盖默认委托。如果您想为应用程序中使用的所有 ScrollView 覆盖委托,您可以简单地在 iOS.
上有条件地覆盖 ScrollView
的原型链
(<any>ScrollView.prototype).originalAttachNative = (<any>ScrollView.prototype).attachNative;
(<any>ScrollView.prototype).attachNative = function () {
this.originalAttachNative();
const newDelegate = FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
this._delegate = newDelegate;
this.nativeViewProtected.delegate = newDelegate;
};
如果您想从委托中触发一个事件,
scrollViewDidEndDraggingWillDecelerate(scrollView: UIScrollView, decelerate: boolean) {
const owner = (<WeakRef<ScrollView>>(<any>this._originalDelegate)._owner).get();
if (owner) {
owner.notify({
object: owner,
eventName: "dragEnd",
decelerate: decelerate
});
}
}
现在从Angular开始,您可以收听活动了,
HTML
(dragEnd)="onDragEnd($event)"
TS
onDragEnd(event) {
console.log(event.decelerate);
}
我正在使用 nativescript android 和 ios 应用程序工作 angular application.i 想访问 ios 的滚动视图委托,我被访问了来自本机 ios 的滚动视图委托在 code.but 之后不起作用:
我的 scrollview 委托实现 class:
// import {Injectable, EventEmitter,Output} from "@angular/core";
@ObjCClass(UIScrollViewDelegate)
export class FoodScrollDelegate extends NSObject implements UIScrollViewDelegate
{
public static ObjCProtocols = [UIScrollViewDelegate];
// @Output() yvalue:EventEmitter<any>=new EventEmitter();
private _originalDelegate:UIScrollViewDelegate;
public getY:Number=0;
constructor()
{
super();
}
public static initWithOriginalDelegate(originalDelegate:UIScrollViewDelegate):FoodScrollDelegate{
console.log("Called Method");
let delegate=<FoodScrollDelegate>FoodScrollDelegate.new();
delegate._originalDelegate=originalDelegate;
return delegate;
}
}
我已经像这样设置滚动视图委托:
onScrollLoaded(args)
{
var subscroll=args.object;
var uiscrollview=subscroll.ios;
let tf=<any>this.subMenuScroll;
var newweakref=new WeakRef(uiscrollview);
const newDelegate=FoodScrollDelegate.initWithOriginalDelegate(tf._delegate);
console.log("PrintDelegate",+newDelegate);
uiscrollview.delegate=newDelegate;
}
我的 MenuComponet class 像这样:
import { Component, OnInit, AfterViewInit,ViewChild, ElementRef} from "@angular/core";
import {Page, borderTopRightRadiusProperty} from "ui/page";
import { isIOS, isAndroid } from 'tns-core-modules/platform';
import { RadListView, ListViewEventData } from "nativescript-ui-listview";
import { RestaurentMenuModel,RestaurentSubMenuModel } from "~/app/models/restaurant";
import { ObservableArray } from "tns-core-modules/data/observable-array";
import { run } from "tns-core-modules/application/application";
import { ScrollEventData, ScrollView } from "tns-core-modules/ui/scroll-view/scroll-view";
import { RouterExtensions } from "nativescript-angular/router";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout/stack-layout";
import { Label } from "tns-core-modules/ui/label/label";
import { analyzeAndValidateNgModules } from "@angular/compiler";
import * as utils from "tns-core-modules/utils/utils";
import { setTimeout } from "tns-core-modules/timer";
import { EventData } from "data/observable";
import { FoodScrollDelegate } from "~/app/Utils/scroll_delegate";
declare var UITableViewCellSelectionStyle;
declare var UIView, NSMutableArray, NSIndexPath;
//declare var setShowsHorizontalScrollIndicator;
@Component({
selector:"restaurant_menu",
moduleId:module.id,
templateUrl:"./restaurant_menu.component.html",
styleUrls:["./restaurant_menu.component.css"],
})
export class RestaurantMenu implements OnInit
{
//public cartCount:Number=1;
@ViewChild("ScrollList") scrollList:ElementRef;
@ViewChild("categoryList") categoryList:ElementRef;
public AllMenuList:any;
public cartTotal:any=0;
public cartItem:any=0;
public isCartVisible=false;
incrementItem:any=0;
decrementItem:any=0;
categoryContainer:Label;
subMenuContainers:StackLayout;
offsetValue:any=0;
dummyStatus:any=0;
horizontalOffsetvalue:any=0;
lengthHorizontaloffsetLength:any=0;
public selectedIndex:Number=0;
public scrollEnabled:Boolean=false;
lastItemY:Number=0;
subMenuScroll:ScrollView;
foodScrollDelegate:FoodScrollDelegate;
_delegate:any;
constructor(private page:Page,public routerExtension:RouterExtensions)
{
}
ngOnInit()
{
this.subMenuScroll=this.page.getViewById("subMenuScroll");
//this.subMenuScroll.ios.delegate=FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
//console.log("PrintDelegate"+this.foodScrollDelegate.scrollViewDidEndDraggingWillDecelerate);
// this.foodScrollDelegate=new FoodScrollDelegate();
// this.foodScrollDelegate.yvalue.subscribe(yvalue=>{
// console.log("TheYYValue"+yvalue);
// });
}
public scrollViewDidEndDraggingWillDecelerate?(scrollView: UIScrollView, decelerate: boolean): void {
console.log("WillScrollEnd"+" "+decelerate);
}
public scrollViewDidScroll?(scrollView: UIScrollView): void {
this.getY=scrollView.contentOffset.y;
console.log("Yposition"+this.getY);
//this.yvalue.emit(this.getY);
}
onLoaded(event)
{
const scrollview = event.object;
if (scrollview.ios) {
scrollview.ios.showsHorizontalScrollIndicator = false;
}
else
{
scrollview.android.setHorizontalScrollBarEnabled(false);
}
}
onNavBtnTap()
{
this.routerExtension.backToPreviousPage();
}
}
在 i 中实现了委托 methods.but 它正在工作
ObjCClass
是 ObjCProtocols
的替代语法。您可能不需要两者都做。
加载事件后附加默认委托,因此您的委托可能会再次被覆盖。您将必须扩展 ScrollView 并覆盖 attachNative
方法。
class MyScrollView extends ScrollView {
protected attachNative() {
(<any>ScrollView.prototype).attachNative.call(this);
if (isIOS) {
(<any>this)._delegate = FoodScrollDelegate.initWithOriginalDelegate((<any>this)._delegate);
this.nativeViewProtected.delegate = (<any>this)._delegate;
}
}
}
注册这个 MyScrollView
,
registerElement("MyScrollView", () => MyScrollView);
现在您应该可以在 HTML 中使用 MyScrollView
而不是 ScrollView
,这将覆盖默认委托。如果您想为应用程序中使用的所有 ScrollView 覆盖委托,您可以简单地在 iOS.
ScrollView
的原型链
(<any>ScrollView.prototype).originalAttachNative = (<any>ScrollView.prototype).attachNative;
(<any>ScrollView.prototype).attachNative = function () {
this.originalAttachNative();
const newDelegate = FoodScrollDelegate.initWithOriginalDelegate(this._delegate);
this._delegate = newDelegate;
this.nativeViewProtected.delegate = newDelegate;
};
如果您想从委托中触发一个事件,
scrollViewDidEndDraggingWillDecelerate(scrollView: UIScrollView, decelerate: boolean) {
const owner = (<WeakRef<ScrollView>>(<any>this._originalDelegate)._owner).get();
if (owner) {
owner.notify({
object: owner,
eventName: "dragEnd",
decelerate: decelerate
});
}
}
现在从Angular开始,您可以收听活动了,
HTML
(dragEnd)="onDragEnd($event)"
TS
onDragEnd(event) {
console.log(event.decelerate);
}