Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 将UIView帧设置为与来自不同superview的另一个视图的帧相等_Ios_Swift_Frame - Fatal编程技术网

Ios 将UIView帧设置为与来自不同superview的另一个视图的帧相等

Ios 将UIView帧设置为与来自不同superview的另一个视图的帧相等,ios,swift,frame,Ios,Swift,Frame,我正在创建不同SuperView中的UIView,但我希望将帧设置为彼此相等 这就是我到目前为止所尝试的 let globalPoint = self.view.convert(subViewOfOuterView.frame.origin, to: nil) let frame = CGRect(x: globalPoint.x, y: globalPoint.y, width: self.subViewOfOuterView.frame.width, height: self.subVie

我正在创建不同SuperView中的UIView,但我希望将帧设置为彼此相等

这就是我到目前为止所尝试的

let globalPoint = self.view.convert(subViewOfOuterView.frame.origin, to: nil)
let frame = CGRect(x: globalPoint.x, y: globalPoint.y, width: self.subViewOfOuterView.frame.width, height: self.subViewOfOuterView.frame.height)
subViewOfInnerUIView.frame = frame
但我的观点最终是这样的


使用您提供的对象名称,下面是一个创建第二个视图的示例,也是一个UIButton(InnerUIView的子视图),它将与第一个按钮(drawButton)具有相同的帧。这两个按钮都是主视图中不同超级视图的子视图。我使用了一个UIButton来标记视图,但是UIView的任何其他子类(其框架可以设置)也可以工作

请注意,由于它们具有相同的帧,因此除了具有相同的大小外,它们相对于其超级视图也具有相同的位置

即使有问题的对象位于几个层深或层浅的子视图中,这也应该有效。这不要紧

该示例可以在最新XCode的单个视图中重新创建。希望这有帮助

//: 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()
下面是使两个视图重叠的更新代码。我为更改设置了动画,使其清晰可见,并对特定帧进行了注释,试图解释如何进行更改:

//: 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()
将SubViewOfInreView.frame设置为frame3的最后一行基本上就是您想要的。您可能可以创建一个函数来完成这3行的工作,以使其更简单(将2个子视图作为参数),尽管不可否认,如果视图层次较深,它可能不会这么简单:

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

希望这有帮助

不要乱动相框。使用自动布局。只要OuterUIView和InnerUIView在链的某个位置有一个公共的superview,就可以简单地将两个视图的边约束为一个another@Paulw11我之所以使用帧是因为我在做animationOk,但你可以只使用约束设置动画。@Paulw11我该如何使用自动布局解决这个问题,正如我说的,假设这两个视图在层次结构中的某个位置具有共享父视图,则只需将一个视图的前导锚点约束到另一个视图。与顶部、底部和尾部主播相同,我发布了解决方案的输出,但这两个按钮不可用overlapping@Sam我以为输出就是你想要的效果。让我看看,这样按钮就可以重叠了。应该是一个快速编辑。@Sam我已经更新了我的答案。希望这就是你想要的行为:)所以一切都可以解决这个问题,但在我的实际程序中,只有当应用程序启动时,我才有一个问题,那就是如何使帧彼此相等。这是一张描述它的图片,这是我在github上的项目。这只发生在应用程序启动时,甚至在新游戏启动时都不会发生。我在这里讨论的代码在ViewControllers的第120行和第131行。这个问题与其他问题有关,主要是当应用程序启动和单击newGame时,视图和变量的状态不同。我通过以下方法复制您的代码解决了您的问题:@IBAction func newGame(u-sender:UIButton)并将其移动到ViewDidDisplay,以便在有人单击newGame时复制您的应用程序的状态,而不会出现错误。我还删除了viewDidLoad中的updateViewFromModel调用。我还注意到,与视图的帧和位置相关的一些属性在didLoad和didebeen上有所不同,这就是我将代码放在后者中的原因。
//: 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()