[Swift] ScrollView avec contenu dynamique
Hello,
Je suis en train de devenir fou
Le problème est simple, j'ai une scrollView + contentView et je souhaite rajouter des contenu dynamiquement. Par contre impossible de faire en sorte que la contentSize de la scrollView grossisse. Et j'ai essayé beaucoup de choses !
Voila le code actuel (tout l'autolayout est fait dans le code).
import UIKit
class ViewController: UIViewController {
var scrollView = UIScrollView()
var contentView = UIView()
override func viewDidLoad()
{
super.viewDidLoad()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.backgroundColor = UIColor.blueColor()
view.addSubview(scrollView)
contentView.translatesAutoresizingMaskIntoConstraints = false
contentView.backgroundColor = UIColor.redColor()
scrollView.addSubview(contentView)
let viewDictionary = ["scrollView": scrollView, "contentView": contentView]
var allConstraints = [NSLayoutConstraint]()
let svVerticalConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
"V:|-0-[scrollView]-0-|",
options: [],
metrics: nil,
views: viewDictionary)
allConstraints += svVerticalConstraint
let svHorizontalConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
"H:|-0-[scrollView]-0-|",
options: [],
metrics: nil,
views: viewDictionary)
allConstraints += svHorizontalConstraint
let cvVerticalConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
"V:|[contentView]|",
options: [],
metrics: nil,
views: viewDictionary)
allConstraints += cvVerticalConstraint
let cvHorizontalConstraint = NSLayoutConstraint.constraintsWithVisualFormat(
"H:|[contentView]|",
options: [],
metrics: nil,
views: viewDictionary)
allConstraints += cvHorizontalConstraint
let cvWidthConstraint = NSLayoutConstraint.init(item: contentView, attribute: .Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1, constant: 0)
allConstraints += [cvWidthConstraint]
let cvHeightConstraint = NSLayoutConstraint.init(item: contentView, attribute: .Height, relatedBy: .GreaterThanOrEqual, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 1)
allConstraints += [cvHeightConstraint]
// let cvCenterXConstraint = NSLayoutConstraint.init(item: contentView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1, constant: 0)
//
// allConstraints += [cvCenterXConstraint]
// let cvCenterYConstraint = NSLayoutConstraint.init(item: contentView, attribute: .CenterY, relatedBy: .Equal, toItem: scrollView, attribute: .CenterY, multiplier: 1, constant: 0)
//
// allConstraints += [cvCenterYConstraint]
NSLayoutConstraint.activateConstraints(allConstraints)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func addMessage() {
let random = Int(arc4random_uniform(6))
let text: String!
switch random {
case 0:
text = "Good, better, best. Never let it rest. 'Til your good is better and your better is best."
break
case 1:
text = "Believe in yourself! Have faith in your abilities! Without a humble but reasonable confidence in your own powers you cannot be successful or happy."
break
case 2:
text = "Infuse your life with action. Don't wait for it to happen. Make it happen. Make your own future. Make your own hope. Make your own love. And whatever your beliefs, honor your creator, not by passively waiting for grace to come down from upon high, but by doing what you can to make grace happen... yourself, right now, right down here on Earth."
break
case 3:
text = "If you can dream it, you can do it."
break
case 4:
text = "A creative man is motivated by the desire to achieve, not by the desire to beat others."
break
case 5:
text = "Hello Dude! I'm your friend. I'm here for you."
break
default:
text = ""
}
let message = Message()
message.text = text
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
label.textAlignment = .Left
label.lineBreakMode = .ByWordWrapping
label.text = text
label.font = UIFont.systemFontOfSize(12)
label.textColor = UIColor.blackColor()
label.sizeToFit()
if let lastView = contentView.subviews.last
{
contentView.addSubview(label)
let viewDictionary = ["label": label, "previousView": lastView]
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[label]-|", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: nil, views: viewDictionary)
contentView.addConstraints(horizontalConstraints)
let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[previousView]-20-[label]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: viewDictionary)
contentView.addConstraints(verticalConstraints)
}
else
{
// first view to be added
contentView.addSubview(label)
let viewDictionary = ["label": label]
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-[label]-|", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: nil, views: viewDictionary)
contentView.addConstraints(horizontalConstraints)
let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[label]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: viewDictionary)
contentView.addConstraints(verticalConstraints)
}
}
}
Si quelqu'un a une idée ou un tuto (qui marche), je suis preneur
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Les UILabel c'est juste pour le début, il faut que se soit une scrollview malheureusement.
Euh, j'suis pas sûr d'avoir tout suivi, mais :
C'est ça ?
Je ne vois pas la frame de la contentView bouger, ou alors j'ai zappé un truc, du coup, la contentSize de la scrollView ne change pas.
La contentSize devrait changer automatiquement en fonction de la taille de la contentView, mais en fait c'est la contentView qui ne grandit pas malgré que j'y rajoute du contenu.
Et pour la stackView, j'avais commencé à regardé par la, je vais regarder si ca peut aller.
Avec une stackview ca fonctionne effectivement.
(stack view dans scroll view)
Si j'ai réfère à ce qui est dit (pas testé, mais ça ne semblerait pas idiot) sur SO (post sans "+1/-1, à 0).
Mais il faudrait que ta dernière subView (label) soit reliée à la parentView (contentView) avec un bottomMargin si j'ai bien suivi.
D'après ce que je vois de ton code tu n'as pas mis de contrainte entre le bas de ton dernier label et le bas de ta contentView. Du coup normal que la contentView ne s'agrandisse pas pour coller au bas des labels que tu ajoutes.