Appending Nativescript Views to a native UI view


#1

I am trying to add a nativescript element to an ios view from within a plugin, anybody have any tips? heres what i am doing:

 viewDidLoad() {
        super.viewDidLoad();
        this.cameraDelegate = <any>CamDelegate.initWithOwner(new WeakRef(this));
        let camBtn = new SwiftyCamButton(<any>{frame: UIScreen.mainScreen.bounds});
        camBtn.delegate = this;
        this.view.addSubview(camBtn);

        let overlay = new GridLayout();
        overlay.backgroundColor = new Color("#000");
        overlay.opacity = .7;

        this.view.addSubview(overlay.ios);

        let closeBtn = createBtn(this, CGRectMake(20, 60, 50, 50), 'X', 'closeTapped');
        this.view.addSubview(closeBtn);

    }

That just simply doesnt add anything to the view. This, however works:

        let overlay = UIView.alloc().initWithFrame(UIScreen.mainScreen.bounds);
        overlay.backgroundColor = UIColor.blackColor;
        overlay.alpha = .8;
        this.view.addSubview(overlay);

But I want the benefit of {N}'s layout so I dont need to deal with multiple device sizes.


#2

@bradwaynemartin @sitefinitysteve @wwwalkerrun I know you guys must know the answer here.


#3

Yeah kinda doing this in the FAB but like you said, native iOS

https://github.com/bradmartin/nativescript-floatingactionbutton/blob/master/fab.ios.ts#L42

The Slides plugin though does it all through {N}


#4

Thanks @sitefinitysteve but I’m still not clear on why appending the UIView created by GridLayout is not being appended as a subview to the UIView.

It looks like in FAB you are appending native ios UIImageView to another native View, and in Slides they are appending Nativescript elements to other Nativescript elements.

When I console out overlay.ios, it consoles a UIView. So I cant figure out why its not appending that UIView, but will append the overlay created with UIView.alloc().


#5

Are we sure it’s not adding it? If you debug are there now subviews? I’m wondering if it’s just something like it’s there but like the width\height are 0 thus making it invisible… like it hasn’t done a layout pass or anything because it’s added in the iOS native code?

Like in your working sample you initialize it to the screen size


#6

Yea, that could certainly be in, but I dont know how to initialize a GridView to be a certain size.

I tried adding overlay.width = 100; and overlay.height = 100; and that didnt work.

If I console out a GridLayout, it lists its frame as frame = (0 0; 0 0);. But when I use addChild to add that GridLayout to a nativescript layout, it is 100% width and height of its parent view. So Nativescript is adding some sugar that sizes the UIView to be the size of its parent.

This is the sugar I am interested in, and likely the reason its not working because I am generating a UIView using NativeScript GridLayout, but NativeScript I guess is no longer handling painting the view if I am dealing only in the .ios property.

Does that make sense?


#7

Hi dave,

The recommended approach is to use either only NS Views or only native views. In your case creating GridView and setting its width, height is not enough to actually layout the NS View as it is not in NS view hierarchy. The layout process is asynchronous so it will happen at some point in time but in order to measure and layout views, we need NativeScript view hierarchy. When working directly with native views you bypass NS view hierarchy. That is why you don’t actually see the GridLayout.

So in your case if this GridLayout is used as overlay (and not as a layout container) better switch it with UIView.alloc().initWithFrame(CGRectMake(0, 0, 100, 100)); If should work across different devices because ios uses device independent pixels.

However if need that GridLayout to position views inside it then you have to call view._addView(overlay) where view is the owning nativescript view.
And you will have to override _eachChildView method and return that overlay view (check layout-base module for implementation details about _eachChildView).


#8

Thanks @Hristo. I guess I’ll just stick with native views. What I was trying to achieve was a view that provides a window into the camera view, if that makes sense. Sort of like this:
CloudApp

I can easily achieve this with GridLayout by doing something like:

<GridLayout rows="*, 200, *">
  <StackLayout style="background-color: rgba(0,0,0,0.5);" />
  <StackLayout>
    // This view doesnt have a semi transparent background, and is where you should focus the serial number.
  </StackLayout>
  <StackLayout row="2" style="background-color: rgba(0,0,0,0.5);" />
</GridLayout>

But I have no idea how to do that in iOS native views, especially when considering different size devices. I ended up with this, which is acceptable IMO:
CloudApp

I created those using native iOS views like UIButton & UIView and append them using view.addChild(subview);