Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在自定义UITableViewCell中以编程方式设置布局约束时遇到问题_Ios_Swift_Autolayout_Ios Autolayout - Fatal编程技术网

Ios 在自定义UITableViewCell中以编程方式设置布局约束时遇到问题

Ios 在自定义UITableViewCell中以编程方式设置布局约束时遇到问题,ios,swift,autolayout,ios-autolayout,Ios,Swift,Autolayout,Ios Autolayout,我正在开发一个iOS应用程序,它是一个基本的Pokedex,希望能教我如何使用UIKit,而不是在这个项目中使用故事板。当我运行我的应用程序时,一切都很好。然而,当我向下滚动时,有一些约束会被弄乱,导致按钮出现在屏幕外。我不知道是什么导致了这一切。我认为当一个单元格被重用时,一些约束正在被应用或没有被应用,但我在约束代码中找不到明显的错误 func set(pokemon: Pokemon) { name.text = pokemon.name var spriteName: S

我正在开发一个iOS应用程序,它是一个基本的Pokedex,希望能教我如何使用UIKit,而不是在这个项目中使用故事板。当我运行我的应用程序时,一切都很好。然而,当我向下滚动时,有一些约束会被弄乱,导致按钮出现在屏幕外。我不知道是什么导致了这一切。我认为当一个单元格被重用时,一些约束正在被应用或没有被应用,但我在约束代码中找不到明显的错误

func set(pokemon: Pokemon) {
    name.text = pokemon.name
    var spriteName: String?

    if let pokemonForm = pokemon.form {
        addSubview(form)
        form.text = pokemonForm
        setNameLabelConstraints(hasForm: true)
        setFormLabelConstraints()
        switch pokemonForm {
            case "Mega":
                spriteName = String(pokemon.speciesID) + "-mega-sprite"
            case "Mega X":
                spriteName = String(pokemon.speciesID) + "-mega-x-sprite"
            case "Mega Y":
                spriteName = String(pokemon.speciesID) + "-mega-y-sprite"
            default:
                spriteName = String(pokemon.speciesID) + "-sprite"
        }
    } else {
        spriteName = String(pokemon.id) + "-sprite"
        form.removeFromSuperview()
        setNameLabelConstraints(hasForm: false)
    }
    sprite.image = UIImage(named: spriteName!)
    type1.setTitle(pokemon.type1, for: .normal)
    styleTypeFilterButton(button: type1)
    type1.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControl.Event.touchUpInside)
    if let secondType = pokemon.type2 {
        addSubview(type2)
        type2.setTitle(secondType, for: .normal)
        styleTypeFilterButton(button: type2)
        setType2ButtonConstraints()
        setType1ButtonConstraints(twoButtons: true)
        type2.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControl.Event.touchUpInside)
    } else {
        type2.removeFromSuperview()
        setType1ButtonConstraints(twoButtons: false)
    }

}

func setNameLabelConstraints(hasForm: Bool) {
    name.translatesAutoresizingMaskIntoConstraints = false
    name.leadingAnchor.constraint(equalTo: sprite.trailingAnchor, constant: 20).isActive = true
    if hasForm == false {
        name.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    } else {
        name.heightAnchor.constraint(equalToConstant: 40).isActive = true
        name.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = false
    }
}

func setType1ButtonConstraints(twoButtons: Bool) {
    //type1.translatesAutoresizingMaskIntoConstraints = false
    if twoButtons == true {
        type1.trailingAnchor.constraint(equalTo: type2.leadingAnchor, constant: -15).isActive = true
    } else {
        type1.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -25).isActive = true
    }
}

func setType2ButtonConstraints() {
    //type2.translatesAutoresizingMaskIntoConstraints = false
    type2.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -25).isActive = true
}

func setFormLabelConstraints() {
    form.translatesAutoresizingMaskIntoConstraints = false
    form.leadingAnchor.constraint(equalTo: sprite.trailingAnchor, constant: 20).isActive = true
    form.heightAnchor.constraint(equalToConstant: 40).isActive = true
    form.topAnchor.constraint(equalTo: name.bottomAnchor, constant: -20).isActive = true
    form.font = form.font.withSize(14)
}

func styleTypeFilterButton(button: UIButton) {
    button.translatesAutoresizingMaskIntoConstraints = false
    button.heightAnchor.constraint(equalToConstant: 25).isActive = true
    button.widthAnchor.constraint(equalToConstant: 65).isActive = true
    button.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true

    button.layer.cornerRadius = 12
    button.setTitleColor(UIColor.white, for: .normal)
    button.titleLabel?.font = button.titleLabel?.font.withSize(14)

    switch button.titleLabel?.text {
        case "Normal":
            button.backgroundColor = UIColor(hexValue: "a8a878")
        case "Fighting":
            button.backgroundColor = UIColor(hexValue: "c03028")
        case "Flying":
            button.backgroundColor = UIColor(hexValue: "a890f0")
        case "Poison":
            button.backgroundColor = UIColor(hexValue: "a040a0")
        case "Ground":
            button.backgroundColor = UIColor(hexValue: "e0c068")
        case "Rock":
            button.backgroundColor = UIColor(hexValue: "b8a038")
        case "Bug":
            button.backgroundColor = UIColor(hexValue: "a8b820")
        case "Ghost":
            button.backgroundColor = UIColor(hexValue: "705898")
        case "Steel":
            button.backgroundColor = UIColor(hexValue: "b8b8d0")
        case "Fire":
            button.backgroundColor = UIColor(hexValue: "f08030")
        case "Water":
            button.backgroundColor = UIColor(hexValue: "6890f0")
        case "Grass":
            button.backgroundColor = UIColor(hexValue: "78C850")
        case "Electric":
            button.backgroundColor = UIColor(hexValue: "f8d030")
        case "Psychic":
            button.backgroundColor = UIColor(hexValue: "f85888")
        case "Ice":
            button.backgroundColor = UIColor(hexValue: "98d8d8")
        case "Dragon":
            button.backgroundColor = UIColor(hexValue: "7038f8")
        case "Dark":
            button.backgroundColor = UIColor(hexValue: "705848")
        case "Fairy":
            button.backgroundColor = UIColor(hexValue: "ee99ac")
        case "???":
            button.backgroundColor = UIColor(hexValue: "68a090")
        case "Shadow":
            button.backgroundColor = UIColor(hexValue: "705848")
        default:
            button.backgroundColor = UIColor(hexValue: "a8a878")
    }
}

如果有人能解释为什么在应用程序第一次运行时它的布局是正确的,但在细胞被重复使用后却变得一团糟,我将不胜感激!我以前从未使用过autolayout,因此我的autolayout代码中可能也有错误,但我不确定是否有任何错误。提前谢谢你

我对代码的工作原理进行了一些猜测,但简而言之,问题是在回收单元格时没有删除旧的布局约束

假设一个单元格被创建,对于它必须显示的第一个条目,您调用setType1ButtonConstraintstwoButtons:false。type1现在固定到单元格的后缘。然后该单元格被回收,对于新条目,它必须显示您调用setType2ButtonConstraints,然后调用setType1ButtonConstraintstwoButtons:true。您的代码将把type2固定到单元格的后缘,然后将type1固定在type2之前,但您从未摆脱从第一个条目开始的约束。您现在有一组不可满足的约束,控制台中将有一个关于此的警告,系统必须打破一个


要解决这个问题,您应该保留对这些约束的引用,并在prepareforuse中删除它们。您也可以使用水平视图。

这里的代码太多了。你不必给出你的实现的每一个细节,比如口袋妖怪开关盒的标题标签和颜色。你只需要发布相关部分。看一看,非常感谢!保留一个引用并能够激活/停用约束是我问题的解决方案