How to Get the Frame of a View Inside Another View

How to get the frame of a view inside another view?

I guess you are looking for this method

– convertRect:toView:

// Swift
let frame = imageView.convert(button.frame, to: self.view)

// Objective-C
CGRect frame = [imageView convertRect:button.frame toView:self.view];

Get view's frame in UIView that is not superview

Use the UIView convertRect:toView: method:

CGRect frameRelativeToViewControllerView = [subviewB convertRect:subviewB.bounds toView:viewController.view];

Set UIView frame equal to the frame of another view from a different superview

Using the object names you provided, here is an example that creates a 2nd view, also a UIButton (subViewOfInnerUIView), that will have the same frame as the 1st button (drawButton). Both buttons are subviews of different superviews within the main view. I used a UIButton so I could label the view, but any other subclass of UIView whose frame can be set will also work.

Note that since they have the same frames, aside from having the same size, they also have the same position relative to their superviews.

This should also work even if the objects in question reside in subviews that are several layers deep, or shallow. It should not matter.

The example can be recreated in a single view playground in the latest XCode. Hope this helps!

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view

let subView1 = UIView(frame: CGRect(x: 40, y: 250, width: 300, height: 300))
subView1.backgroundColor = .red
view.addSubview(subView1)

let subView2 = UIView(frame: CGRect(x: 20, y: 50, width: 340, height: 100))
subView2.backgroundColor = .green
view.addSubview(subView2)

let drawButton = UIButton(frame: CGRect(x: subView1.frame.width / 2 - 50, y: 25, width: 150, height: 50))
drawButton.backgroundColor = .blue
drawButton.setTitle("DRAW BTN", for: .normal)
subView1.addSubview(drawButton)

let subViewOfInnerUIView = UIButton()
subViewOfInnerUIView.setTitle("DRAW BTN2", for: .normal)
subViewOfInnerUIView.backgroundColor = .brown
subView2.addSubview(subViewOfInnerUIView)

let frame = view.convert(drawButton.frame, to: nil)
subViewOfInnerUIView.frame = frame
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

Here's the updated code for making the two views overlap. I animated the change so it's clear, and also commented specific frames to try and explain how it was done:

//: A UIKit based Playground for presenting user interface

import UIKit
import PlaygroundSupport

class MyViewController : UIViewController {
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view

let subView1 = UIView(frame: CGRect(x: 40, y: 250, width: 300, height: 300))
subView1.backgroundColor = .red
view.addSubview(subView1)

let subView2 = UIView(frame: CGRect(x: 20, y: 50, width: 340, height: 100))
subView2.backgroundColor = .green
view.addSubview(subView2)

let drawButton = UIButton(frame: CGRect(x: subView1.frame.width / 2 - 50, y: 25, width: 150, height: 50))
drawButton.backgroundColor = .blue
drawButton.setTitle("DRAW BTN", for: .normal)
subView1.addSubview(drawButton)

let subViewOfInnerUIView = UIButton()
subViewOfInnerUIView.setTitle("DRAW BTN2", for: .normal)
subViewOfInnerUIView.backgroundColor = .brown
subView2.addSubview(subViewOfInnerUIView)

let frame1 = drawButton.frame
let frame2 = subView1.convert(drawButton.frame, to: view)
let frame3 = view.convert(frame2, to: subView2)

print(frame1) // original drawButton frame in its superview
print(frame2) // drawButton frame relative to the main view (self.view)
print(frame3) // drawButton frame relative to subView2 (this is the frame you want)

subViewOfInnerUIView.frame = view.convert(drawButton.frame, to: nil)

UIView.animate(withDuration: 5.0, delay: 0.0, options: [.autoreverse, .repeat], animations: {
subViewOfInnerUIView.frame = frame3
}, completion: nil)

subViewOfInnerUIView.frame = frame3

}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

The last line which sets subViewOfInnerUIView.frame to frame3 is basically what you want. You can probably create a function that does the work of these 3 lines to make it easier (taking the 2 subviews as arguments), although admittedly it may not be so simple if the view hierarchy is deep:

    let frame2 = subView1.convert(drawButton.frame, to: view)
let frame3 = view.convert(frame2, to: subView2)
subViewOfInnerUIView.frame = view.convert(drawButton.frame, to: nil)

Hope this helps!

How to get frame of UIView Nested in UIView's - ObjectiveC

You have the right general idea. But it's easier if you use the inner view's bounds, and use self.view to convert:

// assumes innerView is a view somewhere underneath self.view
CGRect innerViewRectRelativeToController =
[self.view convertRect:innerView.bounds fromView:innerView];

This way you only need to specify the view to convert from, and the view to convert to. You don't need to think about what views are in between the two.

Get frame of subview inside a view that's being rotated (CGAffineTransform)

So it sounds like you have a situation like this:

Sample Image

The frame of innerView "relative to the outer view" is unchanged, by definition, since its frame is specified in the coordinate space of its superview. So maybe you're looking for its frame relative to the enclosing rootView. That's an interesting question, since it's no longer axis-aligned and thus "undefined" in some sense. (See the docs for the frame property of UIView regarding non-identity transform.)

I'm not actually sure what you'd get back if you ran innerView.convert (innerView.frame, to: rootView) on this non-axis-aligned rect. Perhaps something like this:

Sample Image

However, you could easily ask for, say, the top-left corner or the center of innerView relative to rootView like so: innerView.convert (innerView.frame.origin, to: rootView).

C# UWP MVVM inject a view inside another view

C# UWP MVVM inject a view inside another view

If you have used MVVM design, you need to bind Frame SourcePageType property with ViewModel's page type property. you just need to update this page type property, the Frame content will be update.

Here is sample code that you could refer.

Is there a way to get a reference to this ScrollViewer inside code and then setting its Frame to the view I want to specify through the NavigationService?

the other way is pass ContentFrame instance to NavigationService. At first you need add new frame property for NavigationService class. And then replace your code frame with MyFrame.

public class NavigationService
{
private Frame MyFrame { get; set; }
public NavigationService(Frame frame)
{
MyFrame = frame;
}
}

Usgae

 var navService = new NavigationService(ContentFrame);

For above design is referring Windows Template Studio NavigationService, it is complete implementation, and you could find the NavigationService initialization process in the shell page.

ViewModel.Initialize(shellFrame, navigationView, KeyboardAccelerators);

How to check to see if one view is on top of another view?

For point checking, you should use

contains function of CGRect... in short this should work

 let view = UIView()
let label = UILabel()

if label.frame.contains(view.frame) {
//Do your stuff...
}

You can use the view hiearchy with Xcode with this button Sample Image

Or you can simply print out on the current viewController subviews

print(self.view.subviews)

this prints out array of UIView subclasses sorted by ascending order of layer on the view... I recommend the first way of debugging :)

How to get subview's frame in the windows' reference (objc)?

The good fact is that I found the solution :

CGRect targetFrame = [self.view convertRect:self.projectTitle.bounds fromView:self.projectTitle];

I'll explain a bit for people who didn't understand like me :

  • [self.view is the view you want to get the frame's coordinates in.

  • convertRect:self.projectTitle.bounds this is for the bounds of the view you want to get the frame's coordinates.

  • fromView:self.projectTitle]; is finally the view you want to get the frame's coordinates.

  • so targerFrame is the frame of your initial view in the window's coordinates reference.

I did missunderstodd the third param, that is the reason why I was wrong !



Related Topics



Leave a reply



Submit