我正在尝试使用UIScrollView,我正在以编程方式添加自动布局。我读了其他SO答案,但没有一个对我有用。我的ScollView正在滚动,但一直到某个点。在那之后,最后一个子视图不再显示。我所做的是,向UIScrollView添加了contentView,并向contentView添加了子视图。所有子视图都是 translatesAutoresizingMaskIntoConstraints = false ,这应该不会根据视图的约束为我提供contentSize,但事实并非如此。我尝试将contentView的底部锁定到scrollview,并将contentview的最后一个子视图的底部锁定到scrollview,但是它不起作用。基本上,contentView中有个卡,其中有 height 个约束。但是它们并没有滚动到最后。无论我做什么,最后一个孩子都不会滚动到最后。这种方法有什么问题?
class NodeSettingViewController: UIViewController,UIScrollViewDelegate {
var scrollView:UIScrollView?
var cellVM:NodeAppCellViewModel?
var contentView:UIView?
override func viewDidLoad() {
super.viewDidLoad()
let img = UIImage(named: "back_arrow")
let size = CGSize(width: 20, height: 20)
UIGraphicsBeginImageContext(size)
img!.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let backButton = UIBarButtonItem(image: image, style: UIBarButtonItemStyle.plain, target: self, action: #selector(closeButtonTapped(_:)))
self.view.backgroundColor = UIColor.white
let appBar = MDCAppBarViewController()
appBar.headerStackView.backgroundColor = UIColor(netHex: Constants.color)
appBar.navigationBar.titleAlignment = .center
appBar.navigationBar.titleTextColor = UIColor.white
appBar.navigationBar.backItem = backButton
appBar.navigationBar.title = cellVM!.appName == nil ? "" : cellVM!.appName!
view.addSubview(appBar.view)
scrollView = UIScrollView()
scrollView!.translatesAutoresizingMaskIntoConstraints=false
contentView = UIView()
contentView!.backgroundColor = UIColor(netHex: Constants.BACKGROUUND_COLOR)
contentView!.translatesAutoresizingMaskIntoConstraints=false
let statusAndImageHolder = StatusAndImageHolderView()
statusAndImageHolder.translatesAutoresizingMaskIntoConstraints=false
statusAndImageHolder.setup(cellVM: cellVM)
contentView!.addSubview(statusAndImageHolder)
let healthCard = HealthCard()
healthCard.setShadowElevation(ShadowElevation.cardResting, for: UIControlState.normal)
healthCard.translatesAutoresizingMaskIntoConstraints=false
healthCard.setup(hubID: cellVM!.nodeApp!.hubId!, nodeID: cellVM!.nodeApp!.nodeId!,nApp: cellVM!.nodeApp)
let upperConstaintHealthCard = NSLayoutConstraint(item: healthCard, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: contentView!.subviews[contentView!.subviews.count-1], attribute: NSLayoutAttribute.bottom, multiplier: 1, constant:10)
let leftConstraintHealthCard = NSLayoutConstraint(item: healthCard, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let rightConstraintHealthCard = NSLayoutConstraint(item: healthCard, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -10)
let heightConstraintHealthCard = NSLayoutConstraint(item: healthCard, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 150)
contentView!.addSubview(healthCard)
let additionalInfoCard = AdditionalInformationCard()
additionalInfoCard.translatesAutoresizingMaskIntoConstraints=false
additionalInfoCard.setShadowElevation(ShadowElevation.cardResting, for: UIControlState.normal)
additionalInfoCard.setup()
let upperConstaintAdditionalInfoCard = NSLayoutConstraint(item: additionalInfoCard, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: contentView!.subviews[contentView!.subviews.count-1], attribute: NSLayoutAttribute.bottom, multiplier: 1, constant:10)
let leftConstraintAdditionalInfoCard = NSLayoutConstraint(item: additionalInfoCard, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let rightConstraintAdditionalInfoCard = NSLayoutConstraint(item: additionalInfoCard, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -10)
let heightConstraintAdditionalInfoCard = NSLayoutConstraint(item: additionalInfoCard, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 270)
contentView!.addSubview(additionalInfoCard)
let upperConstaintHolder = NSLayoutConstraint(item: statusAndImageHolder, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.top, multiplier: 1, constant:0)
let leftConstraintHolder = NSLayoutConstraint(item: statusAndImageHolder, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 0)
let rightConstraintHolder = NSLayoutConstraint(item: statusAndImageHolder, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: contentView, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -0)
let heightConstraintHolder = NSLayoutConstraint(item: statusAndImageHolder, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 150)
scrollView!.addSubview(contentView!)
scrollView!.bringSubview(toFront: contentView!)
self.view.addSubview(scrollView!)
let contentSize = UIScreen.main.bounds.size.width
let contentHeight = UIScreen.main.bounds.size.height-30
let upperConstaintScrollView = NSLayoutConstraint(item: scrollView!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: appBar.view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 0)
let leftConstraintScrollView = NSLayoutConstraint(item: scrollView!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 0)
let rightConstraintScrollView = NSLayoutConstraint(item: scrollView!, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.right, multiplier: 1, constant: -0)
let bottomConstraintScrollView = NSLayoutConstraint(item: scrollView!, attribute: NSLayoutAttribute.bottom, relatedBy: NSLayoutRelation.equal, toItem: self.view, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: -0)
let upperConstaintContentView = NSLayoutConstraint(item: contentView!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: scrollView!, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0)
let leftConstraintContentView = NSLayoutConstraint(item: contentView!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: scrollView!, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 0)
let widthConstraintContentView = NSLayoutConstraint(item: contentView!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentSize)
let heightConstraintContentView = NSLayoutConstraint(item: contentView!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentHeight)
NSLayoutConstraint.activate([upperConstaintScrollView,leftConstraintScrollView,rightConstraintScrollView,bottomConstraintScrollView,upperConstaintContentView,leftConstraintContentView,widthConstraintContentView,heightConstraintContentView,
upperConstaintHolder,leftConstraintHolder,rightConstraintHolder,heightConstraintHolder,
upperConstaintHealthCard,leftConstraintHealthCard,rightConstraintHealthCard,heightConstraintHealthCard,upperConstaintAdditionalInfoCard,leftConstraintAdditionalInfoCard,rightConstraintAdditionalInfoCard,heightConstraintAdditionalInfoCard])
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
@objc func closeButtonTapped(_ sender:Any){
self.dismiss(animated: true, completion: nil)
}
override func viewDidLayoutSubviews() {
scrollView?.isUserInteractionEnabled=true
scrollView!.isScrollEnabled=true
scrollView!.delegate=self
scrollView!.contentSize = contentView!.frame.size
}
}
我正在共享一张卡片,该卡片是该子视图的最后一个孩子。
class AdditionalInformationCard: MDCCard {
var titleLabel:UILabel?
var placeIdLabel:UILabel?
var eIDLabel:UILabel?
var hubIdLabel:UILabel?
var parentIDLabel:UILabel?
var deviceAddressLabel:UILabel?
var appIDLabel:UILabel?
var firmwareVersionLabel:UILabel?
var addedOnLabel:UILabel?
override func awakeFromNib() {
super.awakeFromNib()
}
func setup(){
let cardWidth = UIScreen.main.bounds.size.width-20
let contentWidth = cardWidth-20
titleLabel = UILabel()
titleLabel?.font = UIFont.boldSystemFont(ofSize: 18.0)
titleLabel?.textColor = UIColor(netHex: Constants.color)
titleLabel?.textAlignment = .left
titleLabel?.text = "Additional Information"
titleLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(titleLabel!)
placeIdLabel = UILabel()
placeIdLabel?.textColor = UIColor.gray
placeIdLabel?.text = "Place Id"
placeIdLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(placeIdLabel!)
eIDLabel = UILabel()
eIDLabel?.textColor = UIColor.gray
eIDLabel?.text = "eId"
eIDLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(eIDLabel!)
hubIdLabel = UILabel()
hubIdLabel?.textColor = UIColor.gray
hubIdLabel?.text = "HUB Id"
hubIdLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(hubIdLabel!)
parentIDLabel = UILabel()
parentIDLabel?.textColor = UIColor.gray
parentIDLabel?.text = "Parent Id"
parentIDLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(parentIDLabel!)
deviceAddressLabel = UILabel()
deviceAddressLabel?.textColor = UIColor.gray
deviceAddressLabel?.text = "Device Address"
deviceAddressLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(deviceAddressLabel!)
appIDLabel = UILabel()
appIDLabel?.textColor = UIColor.gray
appIDLabel?.text = "App Id"
appIDLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(appIDLabel!)
firmwareVersionLabel = UILabel()
firmwareVersionLabel?.textColor = UIColor.gray
firmwareVersionLabel?.text = "Firmware Version"
firmwareVersionLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(firmwareVersionLabel!)
addedOnLabel = UILabel()
addedOnLabel?.textColor = UIColor.gray
addedOnLabel?.text = "Added On"
addedOnLabel?.translatesAutoresizingMaskIntoConstraints=false
self.addSubview(addedOnLabel!)
let upperConstraintTitle = NSLayoutConstraint(item: titleLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 5)
let leftConstraintTitle = NSLayoutConstraint(item: titleLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let rightConstraintTitle = NSLayoutConstraint(item: titleLabel!, attribute: NSLayoutAttribute.right, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.right, multiplier: 1, constant: 10)
let heightConstraintTitle = NSLayoutConstraint(item: titleLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintPlaceId = NSLayoutConstraint(item: placeIdLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: titleLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 10)
let leftConstraintPlaceId = NSLayoutConstraint(item: placeIdLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintPlaceId = NSLayoutConstraint(item: placeIdLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintPlaceId = NSLayoutConstraint(item: placeIdLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstrainteId = NSLayoutConstraint(item: eIDLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: placeIdLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstrainteId = NSLayoutConstraint(item: eIDLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstrainteId = NSLayoutConstraint(item: eIDLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstrainteId = NSLayoutConstraint(item: eIDLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintHubIdLabel = NSLayoutConstraint(item: hubIdLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: eIDLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstraintHubIdLabel = NSLayoutConstraint(item: hubIdLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintHubIdLabel = NSLayoutConstraint(item: hubIdLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintHubIdLabel = NSLayoutConstraint(item: hubIdLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintParentIdLabel = NSLayoutConstraint(item: parentIDLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: hubIdLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstraintParentIdLabel = NSLayoutConstraint(item: parentIDLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintParentIdLabel = NSLayoutConstraint(item: parentIDLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintParentIdLabel = NSLayoutConstraint(item: parentIDLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintDeiveAddressLabel = NSLayoutConstraint(item: deviceAddressLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: parentIDLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstraintDeiveAddressLabel = NSLayoutConstraint(item: deviceAddressLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintDeiveAddressLabel = NSLayoutConstraint(item: deviceAddressLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintDeiveAddressLabel = NSLayoutConstraint(item: deviceAddressLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintAppId = NSLayoutConstraint(item: appIDLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: deviceAddressLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstraintAppId = NSLayoutConstraint(item: appIDLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintAppId = NSLayoutConstraint(item: appIDLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintAppId = NSLayoutConstraint(item: appIDLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintFirmwareVersion = NSLayoutConstraint(item: firmwareVersionLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: appIDLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstraintFirmwareVersion = NSLayoutConstraint(item: firmwareVersionLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintFirmwareVersion = NSLayoutConstraint(item: firmwareVersionLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintFirmwareVersion = NSLayoutConstraint(item: firmwareVersionLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
let upperConstraintAddedOn = NSLayoutConstraint(item: addedOnLabel!, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: firmwareVersionLabel!, attribute: NSLayoutAttribute.bottom, multiplier: 1, constant: 8)
let leftConstraintAddedOn = NSLayoutConstraint(item: addedOnLabel!, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 10)
let widthConstraintAddedOn = NSLayoutConstraint(item: addedOnLabel!, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: contentWidth/2)
let heightConstraintAddedOn = NSLayoutConstraint(item: addedOnLabel!, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
NSLayoutConstraint.activate([upperConstraintTitle,leftConstraintTitle,rightConstraintTitle,heightConstraintTitle,
upperConstraintPlaceId,leftConstraintPlaceId,widthConstraintPlaceId,heightConstraintPlaceId,
upperConstrainteId,leftConstrainteId,widthConstrainteId,heightConstrainteId,
upperConstraintHubIdLabel,leftConstraintHubIdLabel,widthConstraintHubIdLabel,heightConstraintHubIdLabel,
upperConstraintParentIdLabel,leftConstraintParentIdLabel,widthConstraintParentIdLabel,heightConstraintParentIdLabel,upperConstraintDeiveAddressLabel,leftConstraintDeiveAddressLabel,widthConstraintDeiveAddressLabel,heightConstraintDeiveAddressLabel,
upperConstraintAppId,leftConstraintAppId,widthConstraintAppId,heightConstraintAppId,
upperConstraintFirmwareVersion,leftConstraintFirmwareVersion,widthConstraintFirmwareVersion,heightConstraintFirmwareVersion,upperConstraintAddedOn,leftConstraintAddedOn,widthConstraintAddedOn,heightConstraintAddedOn])
}
}