调用和添加到 UIScrollview 时未设置自定义 UIView class 的属性
Properties for custom UIView class not being set when called and added to a UIScrollview
我有一个简单的 UIView class,我想将其添加到 UIScrollView。我已经能够将 UIView 作为数组添加到 UIScrollView 而没有任何问题,除了当我尝试设置其中一个视图属性(例如图像或某些文本)时,当我将 UIView 添加到UIS 滚动视图。我希望这是有道理的。这是代码:
对于 UIView class:
import UIKit
class ScrollViewSlide: UIView {
lazy var mainImageForSubview : UIImageView = {
let mI = UIImageView()
mI.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
return mI
}()
lazy var mainLabel : UILabel = {
let mL = UILabel()
mL.frame = CGRect(x: 0, y: 0, width: 200, height: 30)
mL.center.x = center.x
mL.center.y = center.y
return mL
}()
//initWithFrame to init view from code
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
backgroundColor = .white
contentMode = .scaleAspectFit
addSubview(mainImageForSubview)
addSubview(mainLabel)
}
}
这是主要的 ViewController 代码:
import UIKit
import TinyConstraints
class ViewController: UIViewController, UIScrollViewDelegate {
// MARK: - Properties
lazy var contentViewSize = CGSize(width: self.view.frame.width * 3, height: self.view.frame.height * 0.6)
// MARK: - Views
lazy var pageIndicator : UIPageControl = {
let pI = UIPageControl()
pI.frame = CGRect()
return pI
}()
lazy var scrollView : UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .white
view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height * 0.6)
view.contentSize = contentViewSize
view.delegate = self
return view
}()
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .white
view.addSubview(scrollView)
let mySlides = loadSlides()
setUpViewsForScrollView(slides: mySlides)
scrollView.isPagingEnabled = true
loadPageIndicator(mySlides)
}
func loadSlides() -> [UIView] {
let container1 = ScrollViewSlide()
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
let container2 = ScrollViewSlide()
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
let container3 = ScrollViewSlide()
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
return [container1, container2, container3]
}
func setUpViewsForScrollView(slides : [UIView]) {
for container in slides {
scrollView.addSubview(container)
}
}
func loadPageIndicator(_ mySlides : [UIView]) {
let myPageIndicator = pageIndicator
myPageIndicator.numberOfPages = mySlides.count
myPageIndicator.backgroundColor = .black
myPageIndicator.frame = CGRect(x: self.view.frame.width * 0.5, y: 500, width: 100, height: 30)
myPageIndicator.center.x = view.center.x
self.view.addSubview(myPageIndicator)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageIndicator.currentPage = Int(pageIndex)
}
}
特别是当我在 loadSlides() 中设置属性时,它们不会转移到 UIScrollView。它只是白色背景的空白。
有什么想法吗?
通过将 loadSlides()
函数更改为:
,您可以更接近您想要的结果
func loadSlides() -> [UIView] {
// instantiate with a frame
let container1 = ScrollViewSlide(frame: scrollView.frame)
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
// instantiate with a frame
let container2 = ScrollViewSlide(frame: scrollView.frame)
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
// move container2 to the right of container1
container2.frame.origin.x = container1.frame.origin.x + container1.frame.size.width
// instantiate with a frame
let container3 = ScrollViewSlide(frame: scrollView.frame)
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
// move container3 to the right of container2
container3.frame.origin.x = container2.frame.origin.x + container2.frame.size.width
return [container1, container2, container3]
}
但是,正如我在评论中提到的,从长远来看,通过学习自动布局 运行,你会过得更好。
编辑
这是您的代码,已修改为使用自动布局而不是显式框架:
class ScrollViewSlide: UIView {
lazy var mainImageForSubview : UIImageView = {
let mI = UIImageView()
return mI
}()
lazy var mainLabel : UILabel = {
let mL = UILabel()
return mL
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
backgroundColor = .white
contentMode = .scaleAspectFit
addSubview(mainImageForSubview)
addSubview(mainLabel)
mainImageForSubview.translatesAutoresizingMaskIntoConstraints = false
mainLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// constrain main image to all 4 sides
mainImageForSubview.topAnchor.constraint(equalTo: topAnchor),
mainImageForSubview.bottomAnchor.constraint(equalTo: bottomAnchor),
mainImageForSubview.leadingAnchor.constraint(equalTo: leadingAnchor),
mainImageForSubview.trailingAnchor.constraint(equalTo: trailingAnchor),
// constrain main label centered X and Y, height = 30
mainLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
mainLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
mainLabel.heightAnchor.constraint(equalToConstant: 30.0),
])
}
}
class SlidesViewController: UIViewController, UIScrollViewDelegate {
// MARK: - Properties
// using auto-layout, so no need for contentViewSize
//lazy var contentViewSize = CGSize(width: self.view.frame.width * 3, height: self.view.frame.height * 0.6)
// MARK: - Views
lazy var pageIndicator : UIPageControl = {
let pI = UIPageControl()
pI.frame = CGRect()
return pI
}()
lazy var scrollView : UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .white
view.delegate = self
return view
}()
lazy var stackView: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.alignment = .fill
v.distribution = .fill
v.spacing = 0
return v
}()
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .white
view.addSubview(scrollView)
scrollView.addSubview(stackView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false
let mySlides = loadSlides()
setUpViewsForScrollView(slides: mySlides)
loadPageIndicator(mySlides)
let v = view.safeAreaLayoutGuide
let g = scrollView.contentLayoutGuide
NSLayoutConstraint.activate([
// constrain scroll view to top, leading, trailing
scrollView.topAnchor.constraint(equalTo: v.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: v.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: v.trailingAnchor),
// constrain scroll view height to 60% of view height
scrollView.heightAnchor.constraint(equalTo: v.heightAnchor, multiplier: 0.6),
// constrain stack view to all 4 sides of scroll view's contentLayoutGuide
stackView.topAnchor.constraint(equalTo: g.topAnchor),
stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// constrain stack view height equal to scroll view height
stackView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
])
scrollView.isPagingEnabled = true
}
func loadSlides() -> [UIView] {
let container1 = ScrollViewSlide()
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
let container2 = ScrollViewSlide()
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
let container3 = ScrollViewSlide()
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
return [container1, container2, container3]
}
func setUpViewsForScrollView(slides : [UIView]) {
for container in slides {
stackView.addArrangedSubview(container)
container.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
}
func loadPageIndicator(_ mySlides : [UIView]) {
let myPageIndicator = pageIndicator
myPageIndicator.numberOfPages = mySlides.count
myPageIndicator.backgroundColor = .black
self.view.addSubview(myPageIndicator)
myPageIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// width = 100, height = 30
myPageIndicator.widthAnchor.constraint(equalToConstant: 100.0),
myPageIndicator.heightAnchor.constraint(equalToConstant: 30.0),
// constrain top to 12-pts below bottom of scroll view
myPageIndicator.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 12.0),
// constrain centerX to centerX of scroll view
myPageIndicator.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor, constant: 0.0),
])
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageIndicator.currentPage = Int(pageIndex)
}
}
我有一个简单的 UIView class,我想将其添加到 UIScrollView。我已经能够将 UIView 作为数组添加到 UIScrollView 而没有任何问题,除了当我尝试设置其中一个视图属性(例如图像或某些文本)时,当我将 UIView 添加到UIS 滚动视图。我希望这是有道理的。这是代码:
对于 UIView class:
import UIKit
class ScrollViewSlide: UIView {
lazy var mainImageForSubview : UIImageView = {
let mI = UIImageView()
mI.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)
return mI
}()
lazy var mainLabel : UILabel = {
let mL = UILabel()
mL.frame = CGRect(x: 0, y: 0, width: 200, height: 30)
mL.center.x = center.x
mL.center.y = center.y
return mL
}()
//initWithFrame to init view from code
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
backgroundColor = .white
contentMode = .scaleAspectFit
addSubview(mainImageForSubview)
addSubview(mainLabel)
}
}
这是主要的 ViewController 代码:
import UIKit
import TinyConstraints
class ViewController: UIViewController, UIScrollViewDelegate {
// MARK: - Properties
lazy var contentViewSize = CGSize(width: self.view.frame.width * 3, height: self.view.frame.height * 0.6)
// MARK: - Views
lazy var pageIndicator : UIPageControl = {
let pI = UIPageControl()
pI.frame = CGRect()
return pI
}()
lazy var scrollView : UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .white
view.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height * 0.6)
view.contentSize = contentViewSize
view.delegate = self
return view
}()
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .white
view.addSubview(scrollView)
let mySlides = loadSlides()
setUpViewsForScrollView(slides: mySlides)
scrollView.isPagingEnabled = true
loadPageIndicator(mySlides)
}
func loadSlides() -> [UIView] {
let container1 = ScrollViewSlide()
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
let container2 = ScrollViewSlide()
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
let container3 = ScrollViewSlide()
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
return [container1, container2, container3]
}
func setUpViewsForScrollView(slides : [UIView]) {
for container in slides {
scrollView.addSubview(container)
}
}
func loadPageIndicator(_ mySlides : [UIView]) {
let myPageIndicator = pageIndicator
myPageIndicator.numberOfPages = mySlides.count
myPageIndicator.backgroundColor = .black
myPageIndicator.frame = CGRect(x: self.view.frame.width * 0.5, y: 500, width: 100, height: 30)
myPageIndicator.center.x = view.center.x
self.view.addSubview(myPageIndicator)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageIndicator.currentPage = Int(pageIndex)
}
}
特别是当我在 loadSlides() 中设置属性时,它们不会转移到 UIScrollView。它只是白色背景的空白。
有什么想法吗?
通过将 loadSlides()
函数更改为:
func loadSlides() -> [UIView] {
// instantiate with a frame
let container1 = ScrollViewSlide(frame: scrollView.frame)
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
// instantiate with a frame
let container2 = ScrollViewSlide(frame: scrollView.frame)
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
// move container2 to the right of container1
container2.frame.origin.x = container1.frame.origin.x + container1.frame.size.width
// instantiate with a frame
let container3 = ScrollViewSlide(frame: scrollView.frame)
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
// move container3 to the right of container2
container3.frame.origin.x = container2.frame.origin.x + container2.frame.size.width
return [container1, container2, container3]
}
但是,正如我在评论中提到的,从长远来看,通过学习自动布局 运行,你会过得更好。
编辑
这是您的代码,已修改为使用自动布局而不是显式框架:
class ScrollViewSlide: UIView {
lazy var mainImageForSubview : UIImageView = {
let mI = UIImageView()
return mI
}()
lazy var mainLabel : UILabel = {
let mL = UILabel()
return mL
}()
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
backgroundColor = .white
contentMode = .scaleAspectFit
addSubview(mainImageForSubview)
addSubview(mainLabel)
mainImageForSubview.translatesAutoresizingMaskIntoConstraints = false
mainLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// constrain main image to all 4 sides
mainImageForSubview.topAnchor.constraint(equalTo: topAnchor),
mainImageForSubview.bottomAnchor.constraint(equalTo: bottomAnchor),
mainImageForSubview.leadingAnchor.constraint(equalTo: leadingAnchor),
mainImageForSubview.trailingAnchor.constraint(equalTo: trailingAnchor),
// constrain main label centered X and Y, height = 30
mainLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
mainLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
mainLabel.heightAnchor.constraint(equalToConstant: 30.0),
])
}
}
class SlidesViewController: UIViewController, UIScrollViewDelegate {
// MARK: - Properties
// using auto-layout, so no need for contentViewSize
//lazy var contentViewSize = CGSize(width: self.view.frame.width * 3, height: self.view.frame.height * 0.6)
// MARK: - Views
lazy var pageIndicator : UIPageControl = {
let pI = UIPageControl()
pI.frame = CGRect()
return pI
}()
lazy var scrollView : UIScrollView = {
let view = UIScrollView(frame: .zero)
view.backgroundColor = .white
view.delegate = self
return view
}()
lazy var stackView: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.alignment = .fill
v.distribution = .fill
v.spacing = 0
return v
}()
// MARK: - View Controller Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
view.backgroundColor = .white
view.addSubview(scrollView)
scrollView.addSubview(stackView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
stackView.translatesAutoresizingMaskIntoConstraints = false
let mySlides = loadSlides()
setUpViewsForScrollView(slides: mySlides)
loadPageIndicator(mySlides)
let v = view.safeAreaLayoutGuide
let g = scrollView.contentLayoutGuide
NSLayoutConstraint.activate([
// constrain scroll view to top, leading, trailing
scrollView.topAnchor.constraint(equalTo: v.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: v.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: v.trailingAnchor),
// constrain scroll view height to 60% of view height
scrollView.heightAnchor.constraint(equalTo: v.heightAnchor, multiplier: 0.6),
// constrain stack view to all 4 sides of scroll view's contentLayoutGuide
stackView.topAnchor.constraint(equalTo: g.topAnchor),
stackView.bottomAnchor.constraint(equalTo: g.bottomAnchor),
stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor),
// constrain stack view height equal to scroll view height
stackView.heightAnchor.constraint(equalTo: scrollView.heightAnchor),
])
scrollView.isPagingEnabled = true
}
func loadSlides() -> [UIView] {
let container1 = ScrollViewSlide()
container1.mainImageForSubview.image = UIImage(named: "cricket1")
container1.mainLabel.text = "Container1"
let container2 = ScrollViewSlide()
container2.mainImageForSubview.image = UIImage(named: "cricket2")
container2.mainLabel.text = "Container2"
let container3 = ScrollViewSlide()
container3.mainImageForSubview.image = UIImage(named: "crisp_ocean")
container3.mainLabel.text = "Container3"
return [container1, container2, container3]
}
func setUpViewsForScrollView(slides : [UIView]) {
for container in slides {
stackView.addArrangedSubview(container)
container.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
}
func loadPageIndicator(_ mySlides : [UIView]) {
let myPageIndicator = pageIndicator
myPageIndicator.numberOfPages = mySlides.count
myPageIndicator.backgroundColor = .black
self.view.addSubview(myPageIndicator)
myPageIndicator.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
// width = 100, height = 30
myPageIndicator.widthAnchor.constraint(equalToConstant: 100.0),
myPageIndicator.heightAnchor.constraint(equalToConstant: 30.0),
// constrain top to 12-pts below bottom of scroll view
myPageIndicator.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 12.0),
// constrain centerX to centerX of scroll view
myPageIndicator.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor, constant: 0.0),
])
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
pageIndicator.currentPage = Int(pageIndex)
}
}