我正在尝试在页面中间创建一个如下所示的布局元素,并利用UIPageViewController
来做到这一点。
我在容器视图中嵌入了UIPageViewController
。卡元素的内容具有由AutoLayout确定的高度,并朝着边缘水平延伸,并且卡具有最大宽度,之后它将保持居中。但是我遇到了一个奇怪的问题。当我将card元素的VC设置为我的UIPageViewController
的内容时,单个页面的大小基本上可以正确调整,但是其来源不在pageVC的内容视图的范围之内。
我在一个很小的测试项目中重新创建了问题。这是情节提要和相关限制:
这是我的代码:
class ViewController: UIViewController {
var pageController: UIPageViewController!
override func viewDidLoad() {
super.viewDidLoad()
guard let vc = storyboard?.instantiateViewController(withIdentifier: "PageView") else { return }
pageController.setViewControllers([vc], direction: .forward, animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dest = segue.destination as? UIPageViewController {
pageController = dest
}
}
}
class SinglePageViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.translatesAutoresizingMaskIntoConstraints = false
}
}
这是我实际上得到的:
我尝试在view.autoresizingMask = [.flexibleWidth, .flexibleLeftMargin, .flexibleRightMargin]
中设置view.translatesAutoresizingMaskIntoConstraints = false
而不是SinglePageViewController
,这给了它正确的前导,尾随和宽度约束,但是后来我无法摆脱UIView-Encapsulated-Layout-Height: self.height = 0
约束。没有系统约束可以解决原点错位问题,因此我不知道如何进一步调试。层次结构中位于较高位置的所有视图的高度均为0,位于较低位置的所有视图均已正确放置。如果将SinglePageViewController
直接嵌入到容器视图中,则布局会很完美,但是如果将UIPageViewController
放在两者之间,则会损坏。
为什么UIPageViewController
不能约束其中的页面以使其视图边界匹配?有什么办法可以使它正常工作?
首先,您不应该这样做:
override func viewDidLoad() {
super.viewDidLoad()
// don't do this
//view.translatesAutoresizingMaskIntoConstraints = false
}
[从情节提要板实例化视图时,它们会加载适当的调整大小蒙版...视图控制器的“根”视图需要 translatesAutoresizingMaskIntoConstraints
设置为true
,以便布局正常工作。
删除该行可能会把您带到需要的位置,但我认为您设置了一些错误的约束。
这是我设置的情节提要的外观:
然后,使用此代码:
//
// EmbeddedPageViewViewController.swift
// Created by Don Mag on 5/21/20.
//
import UIKit
class EmbeddedPageViewViewController: UIViewController {
var pageController: UIPageViewController!
override func viewDidLoad() {
super.viewDidLoad()
guard let vc = storyboard?.instantiateViewController(withIdentifier: "PageView") else { return }
pageController.setViewControllers([vc], direction: .forward, animated: true, completion: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let dest = segue.destination as? UIPageViewController {
pageController = dest
}
}
}
class SinglePageViewController: UIViewController {
@IBOutlet var bkgView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
bkgView.backgroundColor = .white
bkgView.layer.cornerRadius = 8.0
bkgView.layer.shadowColor = UIColor.black.cgColor
bkgView.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
bkgView.layer.shadowRadius = 2.0
bkgView.layer.shadowOpacity = 0.35
}
}
我得到这个结果:
主视图的背景色设置为“哈密瓜”,以使其易于看到UIContainerView
的框架。
旋转为横向:
宽度最大达到325,并且保持居中。
作为参考,这是在不将视图背景设置为白色的情况下的外观:
这是我的故事板的来源:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="hya-IX-JpL">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Embedded Page View View Controller-->
<scene sceneID="TRC-Gf-9JR">
<objects>
<viewController id="hya-IX-JpL" customClass="EmbeddedPageViewViewController" customModule="PassBackNavController" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="gkJ-Gz-CPw">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<containerView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IRh-01-Go2">
<rect key="frame" x="8" y="270" width="359" height="128"/>
<constraints>
<constraint firstAttribute="height" constant="128" id="GT3-zg-F9u"/>
</constraints>
<connections>
<segue destination="tRW-tL-JaM" kind="embed" id="DRB-mh-M2m"/>
</connections>
</containerView>
</subviews>
<color key="backgroundColor" red="1" green="0.83234566450000003" blue="0.47320586440000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="IRh-01-Go2" firstAttribute="leading" secondItem="qBw-JJ-Fx5" secondAttribute="leading" constant="8" id="Aqh-1J-Wli"/>
<constraint firstItem="IRh-01-Go2" firstAttribute="centerY" secondItem="gkJ-Gz-CPw" secondAttribute="centerY" id="NLG-5N-8Lb"/>
<constraint firstItem="qBw-JJ-Fx5" firstAttribute="trailing" secondItem="IRh-01-Go2" secondAttribute="trailing" constant="8" id="oDL-2p-roM"/>
</constraints>
<viewLayoutGuide key="safeArea" id="qBw-JJ-Fx5"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dnU-Gs-r2b" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="119" y="131"/>
</scene>
<!--Single Page View Controller-->
<scene sceneID="L0K-o3-YNb">
<objects>
<viewController storyboardIdentifier="PageView" id="cfk-9g-Gkj" customClass="SinglePageViewController" customModule="PassBackNavController" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="7CL-c5-Z9a">
<rect key="frame" x="0.0" y="0.0" width="375" height="200"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nC5-Ym-QUo">
<rect key="frame" x="25" y="12" width="325" height="176"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="umo-Tg-dpR">
<rect key="frame" x="20" y="78" width="285" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<color key="backgroundColor" red="0.075549371539999993" green="0.79593962429999998" blue="0.99987417460000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="umo-Tg-dpR" firstAttribute="leading" secondItem="nC5-Ym-QUo" secondAttribute="leading" constant="20" id="HXw-12-L1h"/>
<constraint firstAttribute="width" priority="750" constant="325" id="Tfm-wt-KFB"/>
<constraint firstAttribute="trailing" secondItem="umo-Tg-dpR" secondAttribute="trailing" constant="20" id="by3-Y5-AqR"/>
<constraint firstItem="umo-Tg-dpR" firstAttribute="centerY" secondItem="nC5-Ym-QUo" secondAttribute="centerY" id="fIW-R2-QXc"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.97619122270000003" green="0.97633117439999995" blue="0.97616070509999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="nC5-Ym-QUo" firstAttribute="top" secondItem="7CL-c5-Z9a" secondAttribute="top" constant="12" id="ASL-q5-MnJ"/>
<constraint firstItem="nC5-Ym-QUo" firstAttribute="centerX" secondItem="7CL-c5-Z9a" secondAttribute="centerX" id="O2h-f7-lBG"/>
<constraint firstItem="nC5-Ym-QUo" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="7CL-c5-Z9a" secondAttribute="leading" constant="16" id="RWx-xc-AnB"/>
<constraint firstAttribute="bottom" secondItem="nC5-Ym-QUo" secondAttribute="bottom" constant="12" id="gJ0-QG-ApQ"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="nC5-Ym-QUo" secondAttribute="trailing" constant="16" id="mEx-VN-uJ4"/>
</constraints>
<viewLayoutGuide key="safeArea" id="QrT-IP-grh"/>
</view>
<size key="freeformSize" width="375" height="200"/>
<connections>
<outlet property="bkgView" destination="nC5-Ym-QUo" id="dx9-da-bUg"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Lfo-H7-oVB" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="884" y="275"/>
</scene>
<!--Page View Controller-->
<scene sceneID="jMx-mM-wG7">
<objects>
<pageViewController autoresizesArchivedViewToFullSize="NO" transitionStyle="pageCurl" navigationOrientation="horizontal" spineLocation="min" id="tRW-tL-JaM" sceneMemberID="viewController"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="xla-ir-fR9" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="897" y="38"/>
</scene>
</scenes>
</document>