如何从原生ios以原生脚本角度访问UIScrollview委托?

时间:2019-02-22 05:34:39

标签: nativescript nativescript-angular

我正在使用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();
    }


}

在我内部实现了委托方法。但是它在起作用

1 个答案:

答案 0 :(得分:1)

ObjCClassObjCProtocols的替代语法。您可能不需要两者都做。

默认委托在加载事件后附加,因此您的委托可能会再次被覆盖。您将必须扩展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);
}