iOS - Set CollectionView Header with dynamic height - ios

I have a collection view with a Header and no cells.
I've set the header size to be equal to the superview bounds as following:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: view.frame.width, height: view.frame.height)
}
This header has a UITextView in it, which is anchored, as well, to the headers bounds (topAnchor, leftAnchor, bottomAnchor and rightAnchor).
I need the header to be anchored to the collection view height when the keyboard is closed, but anchored to the top of the keyboard when this one is opened, changing its size respectively.
The problem here lies when the text of the headers UITextView subview keeps growing and the text goes behind the keyboard.
Here's a GIF showing what's happening.
The yellow view is the Header
The white view is the TextView with some padding.
When I pass the keyboard the text goes behind it - if I could anchor the header to the bottom of the screen when there's no keyboard and to the bottom of the keyboard when its shown would be great.
Any hint?
Thanks
EDIT ADICIONAL INFO
As #Aravind said I've implemented the Notification listener to fire whenever the keyboard shows or hides.
Since I'm using the UITextView inside the Header class as its subview I've implemented the following:
This is an helper function to anchor my views easily:
extension UIView {
func anchor(top: NSLayoutYAxisAnchor?, left: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, right: NSLayoutXAxisAnchor?, paddingTop: CGFloat, paddinfLeft: CGFloat, paddingBottom: CGFloat, paddingRight: CGFloat, width: CGFloat, height: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top {
topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true
}
if let left = left {
leftAnchor.constraint(equalTo: left, constant: paddinfLeft).isActive = true
}
if let bottom = bottom {
bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true
}
if let right = right {
rightAnchor.constraint(equalTo: right, constant: -paddingRight).isActive = true
}
if width != 0 {
widthAnchor.constraint(equalToConstant: width).isActive = true
}
if height != 0 {
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(inputTextView)
inputTextView.delegate = self
inputTextView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddinfLeft: 12, paddingBottom: 0, paddingRight: 12, width: 0, height: 0)
setupInputTextViewToolbar()
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillShow(_:)),
name: NSNotification.Name.UIKeyboardWillShow,
object: nil)
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillHide(_:)),
name: NSNotification.Name.UIKeyboardWillHide,
object: nil)
}
Then the Show/Hide functions
func keyboardWillShow(_ sender:NSNotification){
guard let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return }
inputTextView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddinfLeft: 12, paddingBottom: keyboardSize.height, paddingRight: 12, width: 0, height: 0)
}
func keyboardWillHide(_ sender:NSNotification){
self.inputTextView.anchor(top: self.topAnchor, left: self.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, paddingTop: 0, paddinfLeft: 12, paddingBottom: 0, paddingRight: 12, width: 0, height: 0)
}
The show function works properly and makes the text view to the remaining screen size so it doesn't stay behind the keyboard, so far so good.
But when I fire the hide function it doesn't resize again to the bottom of the screen.
What maybe causing this?

Here make an outlet of the textView's bottom constraint and change its value when keyboard shows up and when it hides like,
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillShow(_:)),
name: NSNotification.Name.UIKeyboardWillShow,
object: nil)
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillHide(_:)),
name: NSNotification.Name.UIKeyboardWillHide,
object: nil)
}
func keyboardWillShow(_ sender:NSNotification){
let keyboardSize = (sender.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
bottomSpace.constant = (keyboardSize?.height)!
}
func keyboardWillHide(_ sender:NSNotification){
bottomSpace.constant = 0
}

Related

Vertical scrolling with TableView inside horizontal CollectionView

I have a horizontal UICollectionView (with paging) where each cell has a fullscreen UITableView. The parent ViewController has a navigation bar with large titles where an animation occurs during vertical scrolling. However, since my table views are within the horizontal collection view, the large navigation bar does not animate when scrolling.
I have attempted a solution of setting a delegate for the tableview scrolling and then set the y offset of the collection view but the result glitches and does not work correctly.
Here is my current code (without TableView/CollectionView delegate/datasource methods)
class HomeViewController: UIViewController, HomeCellDelegate {
var delegate: HomeViewControllerDelegate!
var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
create()
}
func create() {
view.backgroundColor = .background
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.sectionInset = .zero
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
view.addSubview(collectionView)
collectionView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
collectionView.backgroundColor = .clear
collectionView.showsHorizontalScrollIndicator = false
collectionView.isPagingEnabled = true
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(HomeCell.self, forCellWithReuseIdentifier: "cellID")
}
//Delegate from UICollectionView cell (the table view)
func tableViewDidScroll(_ contentOffset: CGPoint) {
collectionView.contentOffset.y = contentOffset.y //Glitches
}
}
protocol HomeCellDelegate {
func tableViewDidScroll(_ contentOffset: CGPoint)
}
class HomeCell: UICollectionViewCell {
var events = [String]()
let tableView = UITableView()
var delegate: HomeCellDelegate!
override init(frame: CGRect) {
super.init(frame: frame)
create()
}
func create() {
backgroundColor = .clear
addSubview(tableView)
tableView.anchor(top: topAnchor, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
tableView.contentInsetAdjustmentBehavior = .never
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offset = CGPoint(x: 0.0, y: scrollView.contentOffset.y + scrollView.adjustedContentInset.top)
delegate.tableViewDidScroll(offset)
}
required init?(coder: NSCoder) {
fatalError()
}
}

How to resize views for multiple iOS screen sizes using auto layout programmatically

I am using an extension for my auto-layout as such:
extension UIView{
func anchorSize(to view: UIView){
widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
}
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, padding: UIEdgeInsets = .zero, size: CGSize = .zero){
translatesAutoresizingMaskIntoConstraints = false
if let top = top{
topAnchor.constraint(equalTo: top, constant: padding.top).isActive = true
}
if let leading = leading{
leadingAnchor.constraint(equalTo: leading, constant: padding.left).isActive = true
}
if let trailing = trailing{
trailingAnchor.constraint(equalTo: trailing, constant: padding.right).isActive = true
}
if let bottom = bottom{
bottomAnchor.constraint(equalTo: bottom, constant: padding.bottom).isActive = true
}
if size.width != 0 {
widthAnchor.constraint(equalToConstant: size.width).isActive = true
}
if size.height != 0 {
heightAnchor.constraint(equalToConstant: size.height).isActive = true
}
}
}
However, I've come across an issue in which when displaying my views on different screen sizes the views become squished or simply don't fit. How would I go about resizing the views through auto-layout to fit multiple screen sizes? This is also the code for when I apply the constraints to something like a label:
logo.anchor(top: view.safeAreaLayoutGuide.topAnchor, leading: view.safeAreaLayoutGuide.leadingAnchor, bottom: nil, trailing: view.safeAreaLayoutGuide.trailingAnchor, padding: .init(top: 20, left: 0, bottom: 0, right: 0))
logo.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
subLogo.anchor(top: logo.bottomAnchor, leading: logo.leadingAnchor, bottom: nil, trailing: logo.trailingAnchor, padding: .init(top: 20, left: 0, bottom: 0, right: 0))
subLogo.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor).isActive = true
The iPhone 11 is the correct way of how I would auto layout. I really want to universally resize all my views for other devices.
Here are the screenshots of the example devices
Thanks in advance.
If you can show what you are actually talking about from screenshots, would help me a lot to see what’s going on.
By the way you are missing translatesAutoresizingMaskIntoConstraints = false in func anchorSize(). Also what are you trying to achieve by having a negative padding amount for top?

Tableviews delegate eats button click

I got a large UITableViewCell representing a place. Elements of the cell are two Buttons starButton and infoButton. Both of them have a targetAction which never gets executed and I'm clueless why.. All touches are being eaten by the didSelectRowAt by the tableview. The thing that gets me so confused is the fact that It all worked well some hours ago and I did not change properties of the two buttons. Does someone has an idea what's going on?
The Hierarchy looks like this:
UITableView
OverviewTableCell UITableViewCell
dotsButton, thumbnailImageView UIButton , UIImageView
blackView UIView
titleLabel, descriptionLabel, starButton, infoButton UILabel , UIButton
Cell:
class OverviewTableViewCell: UITableViewCell, ReusableView {
lazy var dotsButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: GSSettings.UI.otherIcons.dotsHorizontal)?.withRenderingMode(.alwaysTemplate), for: .normal)
button.setImage(UIImage(named: GSSettings.UI.otherIcons.dotsVertical)?.withRenderingMode(.alwaysTemplate), for: .selected)
button.addTarget(self, action: #selector(seeMore), for: .touchUpInside)
button.fixHeightAndWidth(width: 28, height: 28)
button.tintColor = UIColor.gray
return button
}()
let thumbnailImageView: UIImageView = {
let imageview = UIImageView()
imageview.contentMode = .scaleAspectFill
imageview.clipsToBounds = true
imageview.image = UIImage(named: "testbild")
return imageview
}()
let blackView: UIImageView = {
let imageview = UIImageView()
imageview.backgroundColor = UIColor.black.withAlphaComponent(0.35)
return imageview
}()
let titleLabel : UILabel = {
let label = UILabel()
label.text = "Titel Titel"
label.font = GSSettings.UI.Fonts.helveticaMedium?.withSize(22)
label.textColor = UIColor.white
return label
}()
lazy var starButton: GSFavSpotButton = {
let button = GSFavSpotButton()
button.tintColor = UIColor.white//GSSettings.UI.Colors.nightOrange
button.addTarget(self, action: #selector(handleStarButton), for: .touchUpInside)
return button
}()
lazy var infoButton: GSInfoButton = {
let button = GSInfoButton()
button.tintColor = UIColor.white//GSSettings.UI.Colors.nightOrange
button.addTarget(self, action: #selector(handleInfoButton), for: .touchUpInside)
return button
}()
let addFriendView = GSInviteAFriendView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.clipsToBounds = false
self.selectionStyle = .none
setupSubviews()
setupConstraints()
perform(#selector(printBounds), with: nil, afterDelay: 5)
}
func setupSubviews() {
self.addSubview(dotsButton)
self.addSubview(thumbnailImageView)
thumbnailImageView.addSubview(blackView)
blackView.addSubview(titleLabel)
blackView.addSubview(descriptionLabel)
blackView.addSubview(starButton)
blackView.addSubview(infoButton)
self.addSubview(addFriendView)
blackView.isHidden = true
descriptionLabel.isHidden = true
}
func setupConstraints() {
dotsButton.anchor(top: topAnchor, leading: nil, bottom: nil, trailing: trailingAnchor, paddingTop: 0, paddingLeading: 0, paddingBottom: 0, paddingTrailing: 16, width: 0, height: 0)
thumbnailImageView.anchor(top: dotsButton.bottomAnchor, leading: leadingAnchor, bottom: nil, trailing: trailingAnchor, paddingTop: 4, paddingLeading: 16, paddingBottom: 0, paddingTrailing: 16, width: 0, height: 0)
thumbnailImageView.heightAnchor.constraint(equalTo: thumbnailImageView.widthAnchor, multiplier: 9/16).isActive = true
blackView.fillSuperview(unsafeArea: true)
titleLabel.anchor(top: thumbnailImageView.topAnchor, leading: thumbnailImageView.leadingAnchor, bottom: nil, trailing: starButton.leadingAnchor, paddingTop: 8, paddingLeading: 8, paddingBottom: 0, paddingTrailing: 8, width: 0, height: 20)
infoButton.anchor(top: thumbnailImageView.topAnchor, leading: nil, bottom: nil, trailing: thumbnailImageView.trailingAnchor, paddingTop: 8, paddingLeading: 0, paddingBottom: 0, paddingTrailing: 8, width: 30, height: 30)
starButton.anchor(top: thumbnailImageView.topAnchor, leading: nil, bottom: nil, trailing: infoButton.leadingAnchor, paddingTop: 8, paddingLeading: 0, paddingBottom: 0, paddingTrailing: 4, width: 30, height: 30)
addFriendView.anchor(top: thumbnailImageView.bottomAnchor, leading: nil, bottom: nil, trailing: nil, paddingTop: -GSSettings.UI.Sizes.addFriendButtonSize/2 + 10, paddingLeading: 0, paddingBottom: 0, paddingTrailing: 0, width: GSSettings.UI.Sizes.addFriendButtonSize, height: GSSettings.UI.Sizes.addFriendButtonSize)
addFriendView.centerXAnchor.constraint(equalTo: centerXAnchor, constant: 0).isActive = true
}
#objc func seeMore() {
dotsButton.isSelected.toggle()
if dotsButton.isSelected {
blackView.isHidden = false
} else {
blackView.isHidden = false
}
layoutIfNeeded()
}
#objc func handleStarButton() {
starButton.isSelected.toggle()
}
#objc func handleInfoButton() {
infoButton.isSelected.toggle()
}
#objc func printBounds() {
print("::::")
print(thumbnailImageView.bounds)
print(infoButton.bounds)
print(starButton.bounds)
print("_____")
print(thumbnailImageView.frame)
print(infoButton.frame)
print(starButton.frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension UIView {
func anchor(top: NSLayoutYAxisAnchor?, leading: NSLayoutXAxisAnchor?, bottom: NSLayoutYAxisAnchor?, trailing: NSLayoutXAxisAnchor?, paddingTop: CGFloat, paddingLeading: CGFloat, paddingBottom: CGFloat, paddingTrailing: CGFloat, width: CGFloat, height: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
if let top = top {
topAnchor.constraint(equalTo: top, constant: paddingTop).isActive = true
}
if let leading = leading {
leadingAnchor.constraint(equalTo: leading, constant: paddingLeading).isActive = true
}
if let bottom = bottom {
bottomAnchor.constraint(equalTo: bottom, constant: -paddingBottom).isActive = true
}
if let trailing = trailing {
trailingAnchor.constraint(equalTo: trailing, constant: -paddingTrailing).isActive = true
}
if width != 0 {
widthAnchor.constraint(equalToConstant: width).isActive = true
}
if height != 0 {
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
Tableview:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: OverviewTableViewCell.reuseIdentifier, for: indexPath) as! OverviewTableViewCell
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
delegate?.pushTo()
}
The printBounds() function in the cell shows that the frame and bounds are okay (I guess)
(0.0, 0.0, 382.0, 215.0)
(0.0, 0.0, 30.0, 30.0)
(0.0, 0.0, 30.0, 30.0)
(16.0, 32.0, 382.0, 215.0)
(344.0, 8.0, 30.0, 30.0)
(310.0, 8.0, 30.0, 30.0)
You can try
blackView.isUserInteractionEnabled = true
also add the subviews to
self.contentView and create the constraints of cell subviews with it

scrollview scrolling on iphone x simulator but not other devices

I have the following code which sets up the layout of a signup view.
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.mainWhite()
scrollView.isScrollEnabled = true
scrollView.contentSize = CGSize(width: view.frame.size.width, height: view.frame.size.height)
setupView()
addKeyboardObservers()
assignFirstResponders()
}
func setupView() {
view.addSubview(scrollView)
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true
scrollView.addSubview(logoView)
logoView.anchor(top: scrollView.topAnchor, left: nil, bottom: nil, right: nil, paddingTop: 10, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 110, height: 110)
logoView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
let stackView = UIStackView(arrangedSubviews: [emailTextField, passwordTextField, confirmPasswordTextField, firstNameTextField, lastNameTextField, phoneNumberTextField , signupButton])
stackView.axis = .vertical
stackView.spacing = 4
stackView.distribution = .fillEqually
scrollView.addSubview(stackView)
stackView.anchor(top: logoView.bottomAnchor, left: scrollView.leftAnchor, bottom: nil, right: scrollView.rightAnchor, paddingTop: 8, paddingLeft: 60, paddingBottom: 0, paddingRight: 60, width: 0, height: 350)
stackView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
scrollView.addSubview(alreadyHaveAccountButton)
alreadyHaveAccountButton.anchor(top: stackView.bottomAnchor, left: scrollView.leftAnchor, bottom: nil, right: scrollView.rightAnchor, paddingTop: 12, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 50)
scrollView.addSubview(footerView)
footerView.translatesAutoresizingMaskIntoConstraints = false
footerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
footerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
footerView.heightAnchor.constraint(equalToConstant: 70).isActive = true
footerView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
footerView.addSubview(termsAndPrivacyButton)
termsAndPrivacyButton.translatesAutoresizingMaskIntoConstraints = false
termsAndPrivacyButton.centerXAnchor.constraint(equalTo: footerView.centerXAnchor).isActive = true
termsAndPrivacyButton.centerYAnchor.constraint(equalTo: footerView.centerYAnchor).isActive = true
}
func assignFirstResponders() {
emailTextField.delegate = self
passwordTextField.delegate = self
confirmPasswordTextField.delegate = self
firstNameTextField.delegate = self
lastNameTextField.delegate = self
phoneNumberTextField.delegate = self
}
I need the view to scroll when the keyboard overlaps an input view. And I've seen plenty of solutions for that here that address that.
extension SignupViewController {
func addKeyboardObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(SignupViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(SignupViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
#objc func keyboardWillShow(notification: NSNotification) {
scrollView.isScrollEnabled = true
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.scrollView.contentInset
contentInset.bottom = keyboardFrame.size.height + 15
scrollView.contentInset = contentInset
print("content inset: \(scrollView.contentInset) \nKeyboard frame \(keyboardFrame)")
}
#objc func keyboardWillHide(notification: NSNotification) {
let contentInset:UIEdgeInsets = UIEdgeInsets.zero
scrollView.contentInset = contentInset
scrollView.isScrollEnabled = false
}
}
The issue I'm encountering now is that the scrolling functionality is ONLY working on the iPhone X simulator. When I test on my actual iPhone 6s device, the scrolling does not work. I've tried all all simualtor devices and the scrollign only works on the iphone X simulator which is extremely strange. Has anyone encountered something like this?

Having issues with activating constraints programmatically and getting errors

Last night I posted a question on here where I used storyboards to set the constraints. I decided to test it with anchors and do constraints programmatically.
I am getting this error:
Terminating app due to uncaught exception 'NSGenericException',
reason: 'Unable to activate constraint with anchors
and
because they have no common ancestor. Does the constraint or its
anchors reference items in different view hierarchies? That's
illegal.'
I know this has to do with views not being a subview of a certain other view however, I have checked it plenty of times and I don't know what to do.
here is the code:
import UIKit
import CoreData
class editViewController: UIViewController {
let screenSize: CGRect = UIScreen.main.bounds
let moContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var editnotes: addednotes?
let mainbackgroundview: UIView =
{
let view = UIView()
view.backgroundColor = .black
view.alpha = 0.3
return view
}()
let backgroundview1: UIView =
{
let view = UIView()
view.backgroundColor = .purple
return view
}()
let edittasktextview1: UITextView = {
let tv = UITextView()
tv.backgroundColor = .black
return tv
}()
let cancelButton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Cancel", for: .normal)
button.addTarget(self, action: #selector(handleCancelButton), for:
.touchUpInside)
return button
}()
let doneButton1 : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Done", for: .normal)
button.addTarget(self, action: #selector(handleDoneButton), for: .touchUpInside)
return button
}()
#objc func handleCancelButton() {
edittasktextview1.endEditing(true)
dismiss(animated: true, completion: nil)
}
#objc func handleDoneButton()
{
dismiss(animated: true, completion: nil)
if edittasktextview1.text.isEmpty == true
{
moContext.delete(editnotes!)
}
else
{
editnotes?.sNote = edittasktextview1.text
}
var error: NSError?
do {
// Save The object
try moContext.save()
print("SAVED")
} catch let error1 as NSError {
error = error1
}
edittasktextview1.endEditing(true)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "NotificationID"), object: nil)
}
override func viewDidAppear(_ animated: Bool) {
//add something here
// edittasktextview.becomeFirstResponder()
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.tintColor = UIColor.white
navigationItem.title = "Edit Tasks"
edittasktextview1.text = editnotes?.sNote
backgroundview1.backgroundColor = editnotes?.sPriorityColor
edittasktextview1.backgroundColor = .clear
setupviews()
//adding gesture to the background view to dismiss keyboard
let dismisskeyboardgesture = UITapGestureRecognizer()
dismisskeyboardgesture.addTarget(self, action: #selector(dismisskeyboard))
let maskPath = UIBezierPath.init(roundedRect: self.backgroundview1.bounds, byRoundingCorners:[.topLeft, .topRight], cornerRadii: CGSize.init(width: 20.0, height: 0))
let maskLayer = CAShapeLayer()
maskLayer.frame = self.backgroundview1.bounds
maskLayer.path = maskPath.cgPath
self.backgroundview1.layer.mask = maskLayer
view.backgroundColor = .clear
//view.addGestureRecognizer(dismisskeyboardgesture)
view.addSubview(mainbackgroundview)
mainbackgroundview.addSubview(backgroundview1)
// view.addSubview(backgroundview1)
backgroundview1.addSubview(edittasktextview1)
backgroundview1.addSubview(cancelButton)
backgroundview1.addSubview(doneButton1)
}
#objc func dismisskeyboard()
{
edittasktextview1.endEditing(true)
}
func setupviews()
{
mainbackgroundview.anchorToTop(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
backgroundview1.anchor(view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, topConstant: 45, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
edittasktextview1.anchor(view.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, topConstant: 40, leftConstant: 8, bottomConstant: 0, rightConstant: 8, widthConstant: 0, heightConstant: 150)
cancelButton.anchor(edittasktextview1.bottomAnchor, left: nil, bottom: nil, right: view.rightAnchor, topConstant: 18, leftConstant: 0, bottomConstant: 0, rightConstant: 8, widthConstant: 40, heightConstant: 30)
doneButton1.anchor(edittasktextview1.bottomAnchor, left: view.leftAnchor, bottom: nil, right: nil, topConstant: 18, leftConstant: 8, bottomConstant: 0, rightConstant: 0, widthConstant: 40, heightConstant: 30)
}
}
Help will be appreciated, as I am stuck at this problem for nearly 18 hours :(
UPDATE #1
Not getting the same error now, however, I am not able to set the backgroundview1 on the mainbackgroundview.
I am adding it as a subview:
mainbackgroundview.addSubview(backgroundview1)
In setupviews() I am placing the constraint like so:
NSLayoutConstraint.activate([
backgroundview1.leftAnchor.constraint(equalTo: mainbackgroundview.leftAnchor, constant: 0),
backgroundview1.rightAnchor.constraint(equalTo: mainbackgroundview.rightAnchor, constant: 0),
backgroundview1.bottomAnchor.constraint(equalTo: mainbackgroundview.bottomAnchor, constant: 0),
backgroundview1.topAnchor.constraint(equalTo: mainbackgroundview.topAnchor, constant: 45)
])
Still I am not getting the backgroundview1 to be placed on the mainbackgroundview. The mainbackgroundview is showing up though on the simulator.
I am adding mainbackgroundview like so:
NSLayoutConstraint.activate([
mainbackgroundview.leftAnchor.constraint(equalTo: view.leftAnchor),
mainbackgroundview.rightAnchor.constraint(equalTo: view.rightAnchor),
mainbackgroundview.topAnchor.constraint(equalTo: view.topAnchor),
mainbackgroundview.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
What am I doing wrong now?
In setupViews() function you are adding constraints but not setting them as active. This is a sample anchor constraint that can be added successfully:
myView.bottomAnchor.constraint(equalTo: view.topAnchor,
constant: 8).isActive=true
Try adding .isActive at the end of each of your constraint.
Moreover you can add relevant anchor constraints for example: topAnchor, bottomAnchor, widthAnchor, heightAnchor, leadingAnchor etc. Try simplifying your constraints.

Resources