我试图掌握某种单元测试,因此我们创建模拟用户默认值。
class MockUserDefaults: UserDefaults {
var gameStyleChanged = 0
override func set(_ value: Int, forKey defaultName: String) {
if defaultName == "something" {
someStyleChanged += 1
}
}
}
Run Code Online (Sandbox Code Playgroud)
在 setup() 之后我创建了
mockUserDefaults = MockUserDefaults(suiteName: "testing")!
Run Code Online (Sandbox Code Playgroud)
所以我很困惑,我无法理解 suiteName 的完整含义,我已阅读官方文档,但还不够清楚,请帮助
我尝试实现旋转调整,因此在教程中作者在设置新首选项之前使用了 invalidatelayout 功能。但实际上所有工作都可以在没有 invalidateLayout 的情况下工作,但我之前在另一种情况下尝试过并得到相同的“无”输出。
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
collectionView.collectionViewLayout.invalidateLayout()
let indexPath = IndexPath(item: pageControl.currentPage, section: 0)
//scroll to indexPath after the rotation is going
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
self.collectionView.reloadData()
}
}
Run Code Online (Sandbox Code Playgroud)
那么为什么我们需要 invalidateLayout 呢?(我阅读了文档,但似乎这个功能有点......它似乎什么都不做......我不知道......也许是多余的?)
我只是想在以编程方式滚动到项目时制作自定义动画。因此,当我不编写动画并按单元格默认使用时,不会消失,但是当我将scrolltoItem函数放入UIView.animate函数中时,最后一个单元格首先消失,然后scrollToItem动画。
在最上面的第二张图片中,位于独立游戏单元之前的collectionView首先消失,然后collectionView从独立游戏单元滚动到下一个
为什么会发生这种行为?为什么当我没有以我的方式有目的地对其进行动画处理,而只是使用animated = true func 调用scrollToItem 时,没有任何消除?如果有人知道细胞会发生什么,请给我一个线索。
UIView.animate(withDuration: 10, delay: 0, options: .curveEaseInOut, animations: {
self.appsCollectionView.scrollToItem(at: IndexPath(item: self.actualNumberOfTheCell, section: 0), at: .centeredHorizontally, animated: false)
}, completion: nil)
Run Code Online (Sandbox Code Playgroud) 为什么在早些时候,当我们像这个例子一样在计算属性中调用 self 时,我们需要编写惰性变量,但现在我们不必这样做了。为什么?
let(lazy var in earlier times) pauseButton: UIButton = {
let button = UIButton(type: .system)
let image = UIImage(named: "pause")
button.setImage(image, for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.tintColor = .white
button.addTarget(self, action: #selector(handlePause), for: .touchUpInside)
return button
}()
Run Code Online (Sandbox Code Playgroud) 根据文档,约束实例属性是
视图所具有的约束。
var constraints: [NSLayoutConstraint] { get }
Run Code Online (Sandbox Code Playgroud)
但是当我用创建它们时
SampleView.rightAnchor.constraint(equalTo: right ,constant: rightConstant).isActive = true
Run Code Online (Sandbox Code Playgroud)
所以它给我打印了一个约束
<NSLayoutConstraint:0x1c4281540 UIButton:0x103d1d030'Next'.right == UIView:0x103d04740.right (active)>
Run Code Online (Sandbox Code Playgroud)
但约束属性没有向我显示任何内容。空数组 [],但同时当我定义 heightAnchor 和 widthAnchor 等约束时
sampleView.heightAnchor.constraint(equalToConstant: 50).isActive = true
sampleview.widthAnchor.constraint(equalToConstant: 60).isActive = true, and constraints array is not empty
[<NSLayoutConstraint:0x1c028bd10 UIButton:0x103d1c5e0'Skip'.height == 50 (active)>,
<NSLayoutConstraint:0x1c028bf40 UIButton:0x103d1c5e0'Skip'.width == 60 (active)>]
Run Code Online (Sandbox Code Playgroud)
如果有人知道,为什么会这样?
我正在实现来自远程源的下载请求,并且遇到了@escaping函数的概念。正如苹果所说:
当闭包作为函数的参数传递给闭包时,闭包被认为是对函数的转义,但是在函数返回后会被调用。
但是我实际上注意到(使用断点工具)它在return语句之前调用并实现。
static func fetchFeaturedApps(completionHandler: @escaping ([AppCategory]) -> ()) {
let urlString = "https://api.letsbuildthatapp.com/appstore/featured"
URLSession.shared.dataTask(with: URL(string: urlString)!) {
(data, response,error) -> Void in
if error != nil {
print(error?.localizedDescription)
return
}
do {
let json = try(JSONSerialization.jsonObject(with: data!, options: .mutableContainers)) as! Dictionary<String, Any>
var appCategories = [AppCategory]()
// invokes before return [![enter image description here][1]][1]
completionHandler(appCategories)
for dict in json["categories"] as! [[String: Any]] {
let appCategory = AppCategory()
appCategory.setValuesForKeys(dict)
appCategories.append(appCategory)
}
print(appCategories)
DispatchQueue.main.async {
// completionHandler(appCategories)
}
} catch …Run Code Online (Sandbox Code Playgroud) 当我尝试创建布局约束时,我了解了NSLayoutAnchor类。他们说:
注意
UIView不提供布局边距属性的锚点属性。相反,layoutMarginsGuide属性提供了一个UILayoutGuide对象,该对象表示这些边距。使用指南的锚点属性创建约束
好。但是同时我创建了没有UILayoutGuide属性的布局边距属性的锚属性。
let inputsContainerView = UIView()
inputsContainerView.backgroundColor = UIColor.white
inputsContainerView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(inputsContainerView)
//need x,y,width,height constraints
inputsContainerView.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
inputsContainerView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0).isActive = true
inputsContainerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
inputsContainerView.heightAnchor.constraint(equalToConstant: 150).isActive = true
Run Code Online (Sandbox Code Playgroud)
那么,为什么我们需要UILayoutGuide对象?事实证明,UIView是否为布局边距属性提供锚属性?请如果有人知道我会非常感激。
所以我试图以这种方式加载webView而不是Storyboard
override func loadView() {
let config = WKWebViewConfiguration( )
webView = WKWebView(frame: .zero, configuration : config)
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "https://vk.com")!
webView.load(URLRequest(url: url))
webView.allowsBackForwardNavigationGestures = true
}
Run Code Online (Sandbox Code Playgroud)
显然,webView的框架为零,因此我应该看不到屏幕上的任何内容,但我看到了完整的webView窗口。请也许我没有考虑到重要的事情?
ios ×8
swift ×8
layout ×1
uianimation ×1
uiscrollview ×1
uiview ×1
userdefaults ×1
wkwebview ×1