nativescript - 如何从 NativeScript Angular 中的 native ios 访问 UIScrollview 委托(delegate)?

标签 nativescript nativescript-angular

我正在使用nativescript Angular应用程序工作android和ios应用程序。我想访问ios的 ScrollView 委托(delegate),我通过以下代码从 native ios访问了 ScrollView 委托(delegate)。但它不起作用:

我的 ScrollView 委托(delegate)实现类:

// 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;
    }


}

我已经像这样设置了 ScrollView 委托(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();
    }


}

在 i 内部实现了委托(delegate)方法。但它正在工作

最佳答案

ObjCClassObjCProtocols 的替代语法。您可能不需要同时执行这两项操作。

默认委托(delegate)是在加载事件后附加的,因此您的委托(delegate)可能会再次被覆盖。您必须扩展 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,这将覆盖默认委托(delegate)。如果您想重写应用程序中使用的所有 ScrollView 的委托(delegate),只需在 iOS 上有条件地重写 ScrollView 的原型(prototype)链即可。

(<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;
};

如果您想从委托(delegate)触发事件,

   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 - 如何从 NativeScript Angular 中的 native ios 访问 UIScrollview 委托(delegate)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54820661/

相关文章:

nativescript - 在nativescript中将元素定位在绝对布局的中心

javascript - Nativescript ios - 命令 xcodebuild 失败,退出代码为空

nativescript - 如何修复android ui性能

nativescript - 使用适用于 Android 和 ios 的 Angular NativeScript 的透明选项卡栏和操作栏

nativescript - 如何在 NativeScript 上添加自定义图标字体

ios - 由于 MDFInternationalization 和 MaterialComponents 目录不存在,无法构建 ios

angular - 更新代码后出现空白屏幕 (Angular-NativeScript)

typescript - "__assign is not defined"- NativeScript 对象传播问题

javascript - 在 Angular+Nativescript 中将项目添加到数据库时刷新列表查看项目

javascript - NativeScript 识别页面是否完全呈现