因此,我正在尝试寻找使项目保持整洁并为自己管理的新方法。
我希望这样做的方法是,将所有关系都保留在它自己的快速文件中,然后在需要时调用它。
我将尽力安排我的问题,但如果屏幕截图有所帮助,或者您需要任何其他信息,我会尽力提供。
需要注意的一件事:集合视图应在应用程序首次启动时加载。并且MenuActionLabel.text出口设置为:“Hi”。
但是,当我尝试调用ShowMe()时,CollectionView不会重新加载,而是崩溃,因为Collectioner返回了nil optional。
import UIKit
class UserMenu: UIView, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
struct Variables {
static var myName = "Hi"
}
@IBOutlet weak var Collectioner: UICollectionView!
当我调用以下“ShowMe()”函数时,我得到了“coll:nil”的打印输出。
我通过'UserMenu()。ShowMe()'从ViewController.swift调用该函数
func ShowMe() {
Variables.myName = "Justin"
print("coll: \(self.Collectioner)")
//Collectioner.reloadData()
//^---- causes error - see didSelectItem for my problem...
//returns nil optional...? Why?
}
//testing to find errors
func numberOfSections(in collectionView: UICollectionView) -> Int {
if collectionView == Collectioner {
return 1
} else {
return 0
}
}
//testing to find errors
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView == Collectioner {
return 1
} else {
return 0
}
}
//testing to find errors
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == Collectioner {
let Cell:UserMenuCell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath as IndexPath) as! UserMenuCell
Cell.MenuActionLabel.text = "\(Variables.myName)"
return Cell
} else {
let Cell:UserMenuCell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath as IndexPath) as! UserMenuCell
return Cell
}
}
//testing to find errors
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
cell.alpha = 0
UIView.animate(withDuration: 0.8) {
cell.alpha = 1
}
}
//testing to find errors
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if collectionView == Collectioner {
return CGSize(width: Collectioner.frame.width, height: 50)
} else {
return CGSize(width: Collectioner.frame.width, height: 50)
}
}
//testing to find errors
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
if collectionView == Collectioner {
return 0
} else {
return 0
}
}
我的困惑出现在这里:
/*
When I tap on the cell:
1. The collection view reloads, and the updated data is shown.
2. Yet... if I call reloadData from elsewhere,
the Collectioner outlet returns as an optional nil?
*/
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if collectionView == Collectioner {
print(collectionView)
print(" ")
print(Collectioner)
print(" ")
collectionView.reloadData()
}
}
}
didSelectItemAt的打印输出为:
<UICollectionView: 0x7fd13103a000; frame = (0 0; 314 716); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x60c000242a00>; layer = <CALayer: 0x60c00022d140>; contentOffset: {0, 0}; contentSize: {314, 50}; adjustedContentInset: {0, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x7fd12ef1b450>
some(<UICollectionView: 0x7fd13103a000; frame = (0 0; 314 716); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x60c000242a00>; layer = <CALayer: 0x60c00022d140>; contentOffset: {0, 0}; contentSize: {314, 50}; adjustedContentInset: {0, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x7fd12ef1b450>)
并且收集视图闪烁,表明已重新加载。
那么,当我尝试从其他任何地方重新加载集合视图时,为什么返回零?
请帮忙。这让我疯狂。我已尽我所能想到的一切,并且已经做了很多寻找答案,解决方案的工作,并且愿意接受建议和学习。
我不确定是否需要在启动时以某种方式“确认” IBOutlet,即使一切似乎都可以通过StoryBoard正确连接。
编辑-ViewController.swift:
import UIKit
class ViewController: UIViewController {
let userMenu = UserMenu()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBOutlet weak var button: UIButton!
@IBAction func button(_ sender: Any) {
print("Tapped Button")
UserMenu().ShowMe()
}
}
编辑-Heirachy
干杯,
贾斯汀。
最佳答案
谈谈调用UserMenu().ShowMe()
时会发生什么
UserMenu()
并使用UserMenu
方法初始化一个新的init()
实例。 ShowMe()
方法。 为什么会崩溃? -因为
UserMenu
实例是通过默认的init
方法初始化的,所以没有从Storyboard加载任何内容。当然,在这种情况下,Collectioner
将是nil
并导致崩溃。要解决此问题,您应该将
UserMenu
实例保留在ViewControler
内作为属性(也许将其命名为userMenu
)。每次您要调用ShowMe()
方法时,它都应该为userMenu.ShowMe()
。编辑:将“故事板”中的“用户菜单”视图连接到
@IBOutlet weak var userMenu: UserMenu!
,并在下面使用我的代码。class ViewController: UIViewController {
@IBOutlet weak var userMenu: UserMenu!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@IBOutlet weak var button: UIButton!
@IBAction func button(_ sender: Any) {
print("Tapped Button")
userMenu.ShowMe()
}
}