我正在使用nativescript angular application运行android和ios应用程序。我想访问ios的scrollview委托,我通过以下代码从native ios访问了scrollview委托。
我的scrollview委托实现类:
// 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类如下:
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();
}
}
在我内部实现了委托方法。但是它在起作用
答案 0 :(得分:1)
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);
}