草庐IT

ios - 设备旋转后更新 View

coder 2023-09-16 原文

我正在制作一个可用于横向和纵向的应用程序。 也可以在 scrollView 中移动一些 views(由 NSUserdefault 保存的坐标)。

但我注意到两个大问题:

1) 当我改变 iPhone 的方向时,我的 views 重置到它们的第一个位置。只有当我还没有接触 views 时才会出现此问题。如果我触摸一个 views,其他 views 会在 iPhone 旋转时改变位置。

2) 同样的问题,但是当我滚动时。如果我不触摸我的 views,它们会在我滚动时更改为旧位置,并且只有一次。 ps:问题发生后,如果我触摸一个view,所有的view都会变到好的位置。

我希望我解释得很好,因为英语不是我的第一语言,所以如果我忘记了数据,请告诉我。

请帮我解决这个问题。谢谢

最佳答案

您可以在此处重新定义所有 View 框架:

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
}

这里有一个例子来研究这个问题

ViewController.swift

import UIKit

class ViewController: UIViewController, UIScrollViewDelegate {

var viewToMove = MyView(frame: CGRect(x: 40, y: 40, width: 80, height: 80))
@IBOutlet var scrollView: UIScrollView!

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.


    viewToMove.setupView()

    scrollView.delegate = self
    scrollView.backgroundColor = UIColor.lightGrayColor().colorWithAlphaComponent(0.3)
    scrollView.addSubview(viewToMove)
    scrollView.contentSize = CGSize(width: 800, height: 800)

    let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longPress(_:)))
    viewToMove.addGestureRecognizer(longPressRecognizer)

    updatenavigationItem(UIScreen.mainScreen().bounds.size)

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Find", style: UIBarButtonItemStyle.Plain, target: self, action: #selector(scrollToView))
}

func updatenavigationItem (size:CGSize) {
    navigationItem.title = "contentOffset: (\(scrollView.contentOffset.strings.x), \(scrollView.contentOffset.strings.y))"
    navigationItem.prompt = "frame size: \(size)"
}

func scrollViewDidScroll(scrollView: UIScrollView) {
    updatenavigationItem(UIScreen.mainScreen().bounds.size)
}

func scrollToView() {

    let width = UIScreen.mainScreen().bounds.width
    let height = UIScreen.mainScreen().bounds.height

    let x = self.viewToMove.frame.origin.x-width/2
    let y = self.viewToMove.frame.origin.y-height/2

    let centerPoint = CGPoint(x: x, y: y)
    self.scrollView.setContentOffset(centerPoint, animated: true)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//Called, when long press occurred
func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {
    switch longPressGestureRecognizer.state  {

        case .Began:
            viewToMove.isMoving = true

        case .Changed:
            viewToMove.center = longPressGestureRecognizer.locationInView(scrollView)
            viewToMove.updateTitle()

        case .Ended:
            viewToMove.isMoving = false

        default :
            break
    }
}

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    updatenavigationItem(size)
}
}

MyView.swift

import UIKit

class MyView: UIView {

private var title = UILabel()

func setupView() {

    title = UILabel(frame: self.bounds)
    title.textAlignment = .Center
    title.numberOfLines = 2
    title.font = UIFont.systemFontOfSize(12)
    addSubview(title)

    isMoving = false
    updateTitle()
}

func updateTitle() {
    let x = center.strings.x
    let y = center.strings.y

    title.text = "x: \(x)\ny: \(y)"

}

private var _isMoving = false
var isMoving: Bool {
    set (newValue) {
        if newValue {
            backgroundColor = UIColor.lightGrayColor().colorWithAlphaComponent(0.3)
            layer.borderWidth = 2
            layer.borderColor = UIColor.redColor().CGColor
            title.textColor = UIColor.blackColor()
        } else {
            backgroundColor = UIColor.grayColor()
            layer.borderWidth = 0
            title.textColor = UIColor.whiteColor()
        }
        _isMoving = newValue
    }
    get {
        return _isMoving
    }
}
}

CGPointExtension.swift

import UIKit

extension CGPoint {

var strings: (x:String, y:String) {
    get {
        let format = "%.2f"
        return (String(format: format, x), String(format: format, y))
    }
}
}

Main.storyboard

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="JYS-qU-rv4">
<dependencies>
    <deployment identifier="iOS"/>
    <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
    <!--Title-->
    <scene sceneID="tne-QT-ifu">
        <objects>
            <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_39229415" customModuleProvider="target" sceneMemberID="viewController">
                <layoutGuides>
                    <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                    <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                </layoutGuides>
                <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                    <rect key="frame" x="0.0" y="94" width="600" height="506"/>
                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                    <subviews>
                        <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="b1d-Ez-GEw">
                            <rect key="frame" x="0.0" y="0.0" width="600" height="506"/>
                        </scrollView>
                    </subviews>
                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                    <constraints>
                        <constraint firstItem="b1d-Ez-GEw" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="3nd-VB-tHp"/>
                        <constraint firstItem="b1d-Ez-GEw" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="F0H-xs-R6q"/>
                        <constraint firstItem="b1d-Ez-GEw" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="cq1-PT-JDa"/>
                        <constraint firstAttribute="trailing" secondItem="b1d-Ez-GEw" secondAttribute="trailing" id="pen-6z-bT6"/>
                    </constraints>
                </view>
                <navigationItem key="navigationItem" title="Title" prompt="Prompt" id="cYl-MP-OqU"/>
                <connections>
                    <outlet property="scrollView" destination="b1d-Ez-GEw" id="wWc-h3-6FR"/>
                </connections>
            </viewController>
            <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
        </objects>
        <point key="canvasLocation" x="1447" y="580"/>
    </scene>
    <!--Navigation Controller-->
    <scene sceneID="TvF-x4-hHN">
        <objects>
            <navigationController automaticallyAdjustsScrollViewInsets="NO" id="JYS-qU-rv4" sceneMemberID="viewController">
                <toolbarItems/>
                <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" translucent="NO"/>
                <navigationBar key="navigationBar" contentMode="scaleToFill" translucent="NO" id="EvU-Vd-zk0">
                    <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
                    <autoresizingMask key="autoresizingMask"/>
                </navigationBar>
                <nil name="viewControllers"/>
                <connections>
                    <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="xj1-QQ-ihb"/>
                </connections>
            </navigationController>
            <placeholder placeholderIdentifier="IBFirstResponder" id="pjs-pr-Pd8" userLabel="First Responder" sceneMemberID="firstResponder"/>
        </objects>
        <point key="canvasLocation" x="635" y="580"/>
    </scene>
</scenes>
</document>

你的固定代码

我建议您以编程方式创建 view1 和 view2。

ViewController.swift

import UIKit
class ViewController: UIViewController {

@IBOutlet var scrollView: UIScrollView!

var view1 = UIView(frame: CGRect(x: 50, y: 50, width: 150, height: 150))
var view2 = UIView(frame: CGRect(x: 220, y: 50, width: 150, height: 150))

override func viewDidLoad() {
    super.viewDidLoad()

    scrollView.contentSize.width = 1000
    scrollView.contentSize.height = 1000

    initView(view1, color: UIColor.yellowColor())
    initView(view2, color: UIColor.blueColor())
}

func initView(viewToInit: UIView, color: UIColor) {
    viewToInit.backgroundColor = color
    viewToInit.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(ViewController.dragDrop(_:))))
    scrollView.addSubview(viewToInit)
}

func setupViewsCoordinates() {
    if let coord1 = NSUserDefaults.standardUserDefaults().valueForKey("coord1") as? String {
        self.view1.center = CGPointFromString(coord1)
        NSLog("\(self.view1.center)")
    }

    if let coord2 = NSUserDefaults.standardUserDefaults().valueForKey("coord2") as? String  {
        self.view2.center = CGPointFromString(coord2)
        NSLog("\(self.view2.center)")
    }

}

override func viewDidLayoutSubviews() {
    setupViewsCoordinates()
}

func dragDrop (sender: UIPanGestureRecognizer) {

    if let senderView = sender.view {

        let newPoint = sender.locationInView(scrollView)
        senderView.center = newPoint

        switch sender.state  {

            // case .Began:
            //case .Changed:

        case .Ended:

            switch senderView {
            case view1:
                NSUserDefaults.standardUserDefaults().setValue(NSStringFromCGPoint(newPoint), forKey: "coord1")

            case view2:
                NSUserDefaults.standardUserDefaults().setValue(NSStringFromCGPoint(newPoint), forKey: "coord2")

            default:
                break
            }

        default :
            break
        }
    }
}
}

Main.storyboard

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="sZy-5d-rmJ">
<dependencies>
    <deployment identifier="iOS"/>
    <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
    <!--View Controller-->
    <scene sceneID="tne-QT-ifu">
        <objects>
            <viewController id="BYZ-38-t0r" customClass="ViewController" customModule="stackoverflow_39229415" customModuleProvider="target" sceneMemberID="viewController">
                <layoutGuides>
                    <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                    <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                </layoutGuides>
                <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                    <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                    <subviews>
                        <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iH0-w9-3Vi">
                            <rect key="frame" x="0.0" y="20" width="600" height="580"/>
                            <subviews>
                                <button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="r4F-iB-85e">
                                    <rect key="frame" x="24" y="19" width="46" height="30"/>
                                    <state key="normal" title="back"/>
                                    <connections>
                                        <segue destination="sZy-5d-rmJ" kind="show" id="oqB-nQ-Cbx"/>
                                    </connections>
                                </button>
                            </subviews>
                        </scrollView>
                    </subviews>
                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                    <constraints>
                        <constraint firstItem="iH0-w9-3Vi" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="0JR-2o-xMa"/>
                        <constraint firstItem="iH0-w9-3Vi" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="H6h-8P-2lO"/>
                        <constraint firstItem="iH0-w9-3Vi" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="SXz-HG-hhh"/>
                        <constraint firstAttribute="trailing" secondItem="iH0-w9-3Vi" secondAttribute="trailing" id="s9E-4S-nuH"/>
                    </constraints>
                </view>
                <connections>
                    <outlet property="scrollView" destination="iH0-w9-3Vi" id="y87-TR-x9X"/>
                </connections>
            </viewController>
            <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
        </objects>
        <point key="canvasLocation" x="1064" y="532"/>
    </scene>
    <!--View Controller-->
    <scene sceneID="jm6-I7-f2e">
        <objects>
            <viewController id="sZy-5d-rmJ" sceneMemberID="viewController">
                <layoutGuides>
                    <viewControllerLayoutGuide type="top" id="FVf-Ax-2ZB"/>
                    <viewControllerLayoutGuide type="bottom" id="LjK-dO-wuz"/>
                </layoutGuides>
                <view key="view" contentMode="scaleToFill" id="ERa-Mg-7aJ">
                    <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                    <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                    <subviews>
                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pYW-PU-huc">
                            <rect key="frame" x="269" y="285" width="63" height="30"/>
                            <constraints>
                                <constraint firstAttribute="width" constant="63" id="5JS-Ml-DRK"/>
                                <constraint firstAttribute="height" constant="30" id="UDb-RY-Nvb"/>
                            </constraints>
                            <state key="normal" title="start test"/>
                            <connections>
                                <segue destination="BYZ-38-t0r" kind="show" id="PaJ-ee-tBZ"/>
                            </connections>
                        </button>
                    </subviews>
                    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                    <constraints>
                        <constraint firstItem="pYW-PU-huc" firstAttribute="centerX" secondItem="ERa-Mg-7aJ" secondAttribute="centerX" id="PFN-01-ccJ"/>
                        <constraint firstItem="pYW-PU-huc" firstAttribute="centerY" secondItem="ERa-Mg-7aJ" secondAttribute="centerY" id="ooK-Nd-fOP"/>
                    </constraints>
                </view>
            </viewController>
            <placeholder placeholderIdentifier="IBFirstResponder" id="9JD-Yr-djy" userLabel="First Responder" sceneMemberID="firstResponder"/>
        </objects>
        <point key="canvasLocation" x="170" y="757"/>
    </scene>
</scenes>
</document>

关于ios - 设备旋转后更新 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39229415/

有关ios - 设备旋转后更新 View的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  3. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  4. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  5. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  6. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  9. ruby-on-rails - 复数 for fields_for has_many 关联未显示在 View 中 - 2

    目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi

  10. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

随机推荐