我遵循了一个教程,该程序以编程方式(没有情节提要)构建了一个天气预报应用程序,以显示当前的城市和温度。我正在通过添加UITableView来修改它以显示5天的天气预报,而不只是当前的温度,但是它没有显示出来。
这是我的WeatherView代码:
class WeatherView: UIView, UITableViewDelegate, UITableViewDataSource {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
setupViews()
setupConstraints()
}
private func setupViews() {
self.addSubview(mainStack)
conditionsImageStack.addArrangedSubview(conditionsImageView)
mainStack.addArrangedSubview(conditionsImageStack)
// forecastTable.register(UITableView.self, forCellReuseIdentifier: "forecast")
forecastTable.register(UITableViewCell.self, forCellReuseIdentifier: "forecast")
forecastTable.delegate = self
forecastTable.dataSource = self
mainStack.addArrangedSubview(centerContentStack)
// centerContentStack.addArrangedSubview(temperatureLabel)
centerContentStack.addArrangedSubview(forecastTable)
centerContentStack.addArrangedSubview(cityAndConditionsStack)
cityAndConditionsStack.addArrangedSubview(cityLabel)
cityAndConditionsStack.addArrangedSubview(conditionsLabel)
mainStack.addArrangedSubview(buttonsStack)
buttonsStack.addArrangedSubview(celsiusButton)
buttonsStack.addArrangedSubview(fahrenheitButton)
buttonsStack.addArrangedSubview(UIView(frame: .zero))
}
private func setupConstraints() {
mainStack.pinEdges(to: self)
}
let mainStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.spacing = 10
stackView.isLayoutMarginsRelativeArrangement = true
stackView.layoutMargins = UIEdgeInsets(top: 10, left: 30, bottom: 30, right: 30)
return stackView
}()
let conditionsImageStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .equalSpacing
stackView.alignment = .trailing
stackView.spacing = 10
return stackView
}()
let cityAndConditionsStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.spacing = 10
return stackView
}()
let centerContentStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.alignment = .center
stackView.spacing = 60
return stackView
}()
// TABLE CODE HERE
var animalArray : [String] = ["elephant", "pig", "goat"]
var forecastTable: UITableView = {
let tableView = UITableView()
let estimatedHeight = tableView.numberOfRows(inSection: 3) //You may need to modify as necessary
// let width = parentView.frame.size.width
let width = estimatedHeight
tableView.frame = CGRect(x: 0, y: 0, width: width, height: estimatedHeight)
return tableView
}()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = forecastTable.dequeueReusableCell(withIdentifier: "forecast")
cell?.textLabel!.text = "Success"
return cell!
}
let temperatureLabel: UILabel = {
let label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 144)
label.textColor = .white
label.textAlignment = .center
label.text = "18°"
return label
}()
let cityLabel: UILabel = {
let label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 36)
label.textColor = .white
label.textAlignment = .center
label.text = "Atlanta"
return label
}()
let conditionsLabel: UILabel = {
let label = UILabel(frame: .zero)
label.font = UIFont.systemFont(ofSize: 20)
label.textColor = .white
label.textAlignment = .center
label.text = "Sunny"
return label
}()
let conditionsImageView: UIImageView = {
let image = UIImage(named: "sun")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFit
imageView.widthAnchor.constraint(equalToConstant: image!.size.width).isActive = true
imageView.heightAnchor.constraint(equalToConstant: image!.size.height).isActive = true
return imageView
}()
let celsiusButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("°C", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 73)
button.setTitleColor(.white, for: .normal)
return button
}()
let fahrenheitButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("°F", for: .normal)
button.titleLabel?.font = UIFont.systemFont(ofSize: 73)
button.setTitleColor(.white, for: .normal)
return button
}()
let buttonsStack: UIStackView = {
let stackView = UIStackView(frame: .zero)
stackView.axis = .horizontal
stackView.distribution = .equalCentering
stackView.spacing = 10
return stackView
}()
}
这是我的ViewController代码:
class WeatherViewController: UIViewController {
var mainView: WeatherView! { return self.view as! WeatherView }
let presenter: WeatherPresenter!
init(with presenter: WeatherPresenter){
self.presenter = presenter
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init coder not implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
updateBackground()
}
func updateBackground() {
self.mainView.updateGradient(presenter.backgroundColor)
}
override func loadView() {
self.view = WeatherView(frame: UIScreen.main.bounds)
}
}
这是我的UIView +约束代码:
extension UIView {
func pinEdges(to view: UIView){
self.translatesAutoresizingMaskIntoConstraints = false
self.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
self.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
self.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
self.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}
}
我尝试通过用tableView.frame = CGRect(x: 0, y: 0, width: width, height: estimatedHeight)
设置尺寸来强制显示它,但这没用。
我将表注册到视图类中,而不是视图控制器类中,但是我不确定这是问题还是如何正确对其进行修改。
答案 0 :(得分:1)
您做错了几件事...
首先,在var forecastTable: UITableView = {...}
声明中,有一行:
let estimatedHeight = tableView.numberOfRows(inSection: 3)
但是,此时,表视图没有dataSource
-即使有,您的dataSource也只有section. So the value returned is undefined. If I
print(esttmatedHeight)I get
9223372036854775807 . So you are trying to set the frame of your table view to
9223372036854775807 x 9223372036854775807`
接下来,当您将表视图添加到堆栈视图时,堆栈视图将尝试根据堆栈视图的属性和表视图的固有大小来排列它。但是,此时表视图没有内部大小-您必须使用自动布局属性。
因此,请删除表格视图的框架设置,然后将其添加到堆栈视图中,然后使用:
// I'm guessing you want a height based on number of rows * row height?
// so, something like:
let estimatedHeight = CGFloat(3 * 44)
forecastTable.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
forecastTable.widthAnchor.constraint(equalTo: centerContentStack.widthAnchor),
forecastTable.heightAnchor.constraint(equalToConstant: estimatedHeight),
])
这将使表格视图的宽度与保存表格的centerContentStack
相同,并赋予其高度。
此时,您应该看到表格。
答案 1 :(得分:0)
您要将mainStack添加到superView中,但未指定其尺寸。您需要像这样设置对mainStack的约束,
mainStack.translatesAutoresizingMaskIntoConstraints = false
mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
mainStack.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
mainStack.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
以上代码用mainStack填充了整个超级视图。您可以根据需要修改此代码。