Programatically created UISwitch non-responsive - ios

I have created a table that looks like what you see in the screenshot.
Here is the code:
lazy var contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height)
lazy var scrollView : UIScrollView = {
let scrollView = UIScrollView(frame: view.bounds)
scrollView.backgroundColor = .white
scrollView.frame = self.view.bounds
scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height * 200)
scrollView.autoresizingMask = UIView.AutoresizingMask.flexibleHeight
scrollView.bounces = true
return scrollView
}()
lazy var containerView : UIView = {
let view = UIView()
view.backgroundColor = .white
view.frame.size = contentSize
return view
}()
let weekStack = UIStackView()
weekStack.axis = .vertical
weekStack.distribution = .fillProportionally
weekStack.spacing = 2
containerView.addSubview(weekStack)
weekStack.translatesAutoresizingMaskIntoConstraints = false
weekStack.topAnchor.constraint(equalTo: restaurantImage.bottomAnchor, constant: 20).isActive = true
weekStack.leadingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
weekStack.trailingAnchor.constraint(equalTo: containerView.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
let arrayOfDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
for index in 0...arrayOfDays.count - 1 {
let dayStack = UIStackView()
weekStack.addArrangedSubview(dayStack)
dayStack.axis = .horizontal
dayStack.distribution = .fillEqually
dayStack.spacing = 4
let daySwitch = UISwitch(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
dayStack.addArrangedSubview(daySwitch)
let dayLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 20, height: 0))
dayLabel.text = arrayOfDays[index]
dayLabel.textAlignment = .center
dayLabel.font = UIFont(name: "NexaLight", size: 16)
dayStack.addArrangedSubview(dayLabel)
let startTextField = UITextField(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
startTextField.placeholder = "Open"
startTextField.textAlignment = .center
startTextField.delegate = self
startTextField.text = "9"
startTextField.font = UIFont(name: "NexaLight", size: 16)
dayStack.addArrangedSubview(startTextField)
startTextField.inputView = timePicker
startTextField.inputAccessoryView = toolbar
let closeTextField = UITextField(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
closeTextField.placeholder = "Close"
closeTextField.textAlignment = .center
closeTextField.text = "23"
closeTextField.font = UIFont(name: "NexaLight", size: 16)
closeTextField.delegate = self
dayStack.addArrangedSubview(closeTextField)
closeTextField.inputView = timePicker
closeTextField.inputAccessoryView = toolbar
}
The problem is that the last 2 switches are not responding as shown in the screenshot. I cannot turn them on. I also cannot interact with the last 2 rows of text fields where you see "9" and "23". This is from the simulator by the way.

Related

NavigationItem.titleView is not getting the right size

I'm trying to set a custom view on a large navigationBar, but it insists on staying at 44px.
func setLargeNavBarForSection(_ section: String, subTitle: String, studyLogoName: String) -> Void {
if let navigationBar = self.navigationController?.navigationBar {
navigationBar.barTintColor = .cyan
navigationBar.shadowImage = UIImage()
let customView = UIView(frame: CGRect(x: 0, y: 0, width: navigationBar.frame.width, height: 96.0))
let sectionNameFrame = CGRect(x: 80, y : 23, width : 150, height : 41)
let subTitleFrame = CGRect(x: 80, y: 53, width: 200, height: 14)
let studyImageView = UIImageView(frame: CGRect(x: 20, y: 25, width: 45, height: 45))
studyImageView.image = UIImage(named: studyLogoName)?.imageWithInsets(insets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
studyImageView.contentMode = .scaleAspectFit
studyImageView.backgroundColor = .white
studyImageView.layer.cornerRadius = 22
studyImageView.addShadow(radius: 3, opacity: 0.1, x: 1, y: 2)
let myStudiesButton = UIButton(frame: CGRect(x: navigationBar.frame.width-96, y: 36, width: 76, height: 26))
myStudiesButton.setImage(UIImage(named: "switchStudies"), for: .normal)
myStudiesButton.addTarget(self, action: Selector(("switchStudies")), for: .touchUpInside)
myStudiesButton.showsTouchWhenHighlighted = true
let sectionNameLabel = UILabel(frame: sectionNameFrame)
sectionNameLabel.text = section
sectionNameLabel.textAlignment = .left
sectionNameLabel.font = UIFont(name: "Montserrat-Bold", size: 18)
sectionNameLabel.textColor = .black
let subTitleLabel = UILabel(frame: subTitleFrame)
subTitleLabel.text = subTitle
subTitleLabel.textAlignment = .left
subTitleLabel.font = UIFont(name: "Montserrat-Medium", size: 11)
subTitleLabel.textColor = .blueGrey
// customView.addSubview(studyImageView)
// customView.addSubview(myStudiesButton)
// customView.addSubview(sectionNameLabel)
// customView.addSubview(subTitleLabel)
navigationItem.largeTitleDisplayMode = .always
customView.backgroundColor = .red
navigationItem.titleView = customView
}
}
navigationController?.navigationBar.prefersLargeTitles = true get called in the viewDidLoad on the ViewController.

Why is Page Control not reflecting where I am on the UIScrollView?

After editing my UIScrollView size, page control stopped working.
You can see there are only 3 slides. But (1) Page Control isn't reflecting which slide I'm on and (2) I can only scroll from slide 1 to slide 3.
Here's my code:
func setupSlideScrollView(slides : [Slide]) {
scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: 154)
scrollView.contentSize = CGSize(width: 188 * CGFloat(slides.count) + CGFloat((slides.count - 1) * 10), height: 153)
scrollView.isPagingEnabled = true
var lastCellMaxX: CGFloat = 0
let constantSpacingBetweenCell: CGFloat = 10
for i in 0 ..< slides.count {
slides[i].frame = CGRect(x: lastCellMaxX, y: 0, width: 220, height: 153)
scrollView.addSubview(slides[i])
lastCellMaxX += 188 + constantSpacingBetweenCell
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pageIndex = round(scrollView.contentOffset.x/scrollView.frame.size.width)
pageControl.currentPage = Int(pageIndex)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// This will always round down to zero
// since the contentOffset.x will always be smaller than the frame width...
let pageIndex = round(scrollView.contentOffset.x/scrollView.frame.size.width)
// Possible logic to correct this?
let pageIndex = scrollView.contentOffset.x / (width of a slide)
pageControl.currentPage = Int(pageIndex)
}
-- Updated due to chat --
Your scrollview's frame is fine. However, you need to add a stackview to hold all your slides in order to scroll through it. Scrollviews are a bit tricky since you can't just add views and expect it to be scrollable.
Here is test code I used to create a scrollView that contains stackviews.
func createSlideshow() {
scrollView.translatesAutoresizingMaskIntoConstraints = false
let slide1 = UIView(frame: CGRect(x: 0, y: 0, width: 220, height: 375))
slide1.backgroundColor = UIColor.red
let slide2 = UIView(frame: CGRect(x: 0, y: 0, width: 220, height: 375))
slide2.backgroundColor = UIColor.blue
let slide3 = UIView(frame: CGRect(x: 0, y: 0, width: 220, height: 375))
slide3.backgroundColor = UIColor.yellow
let slides: [UIView] = [slide1, slide2, slide3]
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.alignment = .center
stackView.distribution = .equalCentering
stackView.spacing = 10
for slide in slides {
stackView.addArrangedSubview(slide)
slide.widthAnchor.constraint(equalToConstant: slide.frame.width).isActive = true
slide.heightAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true
}
scrollView.addSubview(stackView)
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
stackView.widthAnchor.constraint(greaterThanOrEqualTo: scrollView.widthAnchor).isActive = true
stackView.heightAnchor.constraint(equalTo: scrollView.heightAnchor).isActive = true
}

Custom NavigationBar in iOS Swift

I'm creating custom navigationbar in swift for every screen. I'm calling this function at viewWillAppear while first time loading it is coming properly if First Time Loading Screen. I move to another screen it is changing. Next View screen navigation title view is shifted. if I came back to previous screen then also it was shiftedenter image description here. I'm unable to find the bug where code was wrong.left and right navigation items are placing fine . But navigationtitle view only getting shifting.
extension UIViewController {
func reightMenuItems(_ isMenuBtn: Bool, _ navigationItem:UINavigationItem) {
if isMenuBtn {
let leftView = UIView()
leftView.backgroundColor = .clear
leftView.frame = CGRect(x: 0, y: 0, width: 40, height: 44)
let menuImage = UIImageView(image:#imageLiteral(resourceName: "MenuIcon"))
menuImage.contentMode = .scaleAspectFit
menuImage.frame = CGRect(x: 2.5, y: 6, width: 35, height: 32)
leftView.addSubview(menuImage)
let followButton = UIButton(type: .system)
followButton.frame = CGRect(x: 0, y: 0, width: 40, height: 44)
followButton.contentEdgeInsets = UIEdgeInsetsMake(0, -20, 0, 0)
followButton.addTarget(self, action: #selector(self.btnClickMenu), for: .touchUpInside)
leftView.addSubview(followButton)
navigationItem.leftBarButtonItems = [UIBarButtonItem(customView: leftView)]
}else{
let leftView = UIView()
leftView.backgroundColor = .clear
leftView.frame = CGRect(x: 0, y: 0, width: 40, height: 44)
let menuImage = UIImageView(image:#imageLiteral(resourceName: "arrow_white-left"))
menuImage.contentMode = .scaleToFill
menuImage.frame = CGRect(x: 12.5, y: 10.5, width: 15, height: 25)
leftView.addSubview(menuImage)
let followButton = UIButton(type: .system)
followButton.frame = CGRect(x: 0, y: 0, width: 40, height: 44)
leftView.addSubview(followButton)
followButton.addTarget(self, action: #selector(self.btnClickBack), for: .touchUpInside)
navigationItem.leftBarButtonItems = [UIBarButtonItem(customView: leftView)]
}
}
fileprivate func leftMenuItems(_ isCart: Bool, _ navigationItem: UINavigationItem) {
//lecftButtons
if isCart {
let reightView = UIView()
reightView.backgroundColor = .clear
reightView.frame = CGRect(x: 0, y: 0, width: 40, height: 44)
let menuImage = UIImageView(image:#imageLiteral(resourceName: "Cart"))
menuImage.contentMode = .scaleToFill
menuImage.frame = CGRect(x: 2.5, y: 6, width: 35, height: 34)
reightView.addSubview(menuImage)
let cartBtn = UIButton(type: .system)
cartBtn.frame = CGRect(x: 0, y: 0, width: 40, height: 44)
reightView.addSubview(cartBtn)
cartBtn.addTarget(self, action: #selector(self.btnClickCart), for: .touchUpInside)
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: reightView)]
}else{
let composeButton = BtnFontBold20()
composeButton.setTitle("Done", for: .normal)
composeButton.titleLabel?.textColor = .white
composeButton.frame = CGRect(x: 0, y: 00, width: 34, height: 44)
composeButton.contentEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 0)
composeButton.addTarget(self, action: #selector(self.btnClickCart), for: .touchUpInside)
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView: composeButton)]
}
}
func setupNavItems(_ navigationItem: UINavigationItem , day:String = "",address:String = "",type:Int,isMenuBtn:Bool,isCart:Bool,title:String = "") {
//NavigationItem
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.isTranslucent = false
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
//Shadow
self.navigationController?.navigationBar.layer.shadowOffset = CGSize(width: 1.5, height: 1.5)
self.navigationController?.navigationBar.layer.shadowRadius = 2.0
self.navigationController?.navigationBar.layer.shadowOpacity = 0.5
//reight Menu Items
reightMenuItems(isMenuBtn, navigationItem)
leftMenuItems(isCart, navigationItem)
let height = navigationController?.navigationBar.frame.height ?? 0
let leftButtonWidth: CGFloat = 90 // left padding
let width2 = AppConstants.screenWidth - leftButtonWidth
print(width2)
let Titleview = UIView(frame: CGRect(x: 0, y: 0, width: width2, height: height))
Titleview.backgroundColor = .clear
navigationItem.titleView = Titleview
if type == 1 {
let dayLbl = FontBold18(frame: CGRect(x: 0, y: 0, width: min(width2/2,40), height: height))
dayLbl.text = day
dayLbl.textColor = .white
dayLbl.textAlignment = .left
dayLbl.numberOfLines = 1
Titleview.addSubview(dayLbl)
let DirectImag = UIImageView()
DirectImag.contentMode = .scaleAspectFit
DirectImag.image = #imageLiteral(resourceName: "RightDirection")
Titleview.addSubview(DirectImag)
DirectImag.translatesAutoresizingMaskIntoConstraints = false
DirectImag.widthAnchor.constraint(equalToConstant: 15).isActive = true
DirectImag.heightAnchor.constraint(equalToConstant: 15).isActive = true
DirectImag.leadingAnchor.constraint(equalTo: dayLbl.trailingAnchor, constant:5).isActive = true
DirectImag.centerYAnchor.constraint(equalTo: dayLbl.centerYAnchor).isActive = true
let dayBtn = UIButton(type: .system)
dayBtn.addTarget(self, action: #selector(self.btnClickASAPType), for: .touchUpInside)
Titleview.addSubview(dayBtn)
dayBtn.translatesAutoresizingMaskIntoConstraints = false
dayBtn.centerYAnchor.constraint(equalTo: dayLbl.centerYAnchor).isActive = true
dayBtn.centerXAnchor.constraint(equalTo: dayLbl.centerXAnchor, constant: 0).isActive = true
dayBtn.heightAnchor.constraint(equalTo: dayLbl.heightAnchor).isActive = true
dayBtn.widthAnchor.constraint(equalTo: dayLbl.widthAnchor , constant:25).isActive = true
let addLbl = FontBold18()
addLbl.textColor = .white
addLbl.textAlignment = .left
addLbl.numberOfLines = 1
Titleview.addSubview(addLbl)
addLbl.text = address
addLbl.translatesAutoresizingMaskIntoConstraints = false
addLbl.leadingAnchor.constraint(equalTo: DirectImag.trailingAnchor,constant:5).isActive = true
addLbl.heightAnchor.constraint(equalToConstant: height).isActive = true
addLbl.centerYAnchor.constraint(equalTo: Titleview.centerYAnchor).isActive = true
addLbl.widthAnchor.constraint(lessThanOrEqualToConstant: (width2 - dayLbl.frame.width) * 0.9).isActive = true
let downImag = UIImageView()
downImag.contentMode = .scaleAspectFit
downImag.image = #imageLiteral(resourceName: "down-arrow-white")
Titleview.addSubview(downImag)
downImag.translatesAutoresizingMaskIntoConstraints = false
downImag.widthAnchor.constraint(equalToConstant: 15).isActive = true
downImag.heightAnchor.constraint(equalToConstant: 15).isActive = true
downImag.leadingAnchor.constraint(equalTo: addLbl.trailingAnchor, constant:5).isActive = true
downImag.centerYAnchor.constraint(equalTo: addLbl.centerYAnchor).isActive = true
let addressBtn = UIButton(type: .system)
addressBtn.backgroundColor = .clear
addressBtn.addTarget(self, action: #selector(self.btnClickAddress), for: .touchUpInside)
Titleview.addSubview(addressBtn)
addressBtn.translatesAutoresizingMaskIntoConstraints = false
addressBtn.centerYAnchor.constraint(equalTo: addLbl.centerYAnchor).isActive = true
addressBtn.leadingAnchor.constraint(equalTo: addLbl.leadingAnchor, constant: 0).isActive = true
addressBtn.heightAnchor.constraint(equalTo: addLbl.heightAnchor).isActive = true
addressBtn.widthAnchor.constraint(equalTo: addLbl.widthAnchor).isActive = true
}
else if type == 2{
let dayLbl = FontBold18()
dayLbl.text = title
dayLbl.textColor = .white
dayLbl.textAlignment = .center
dayLbl.numberOfLines = 1
Titleview.addSubview(dayLbl)
dayLbl.translatesAutoresizingMaskIntoConstraints = false
dayLbl.centerXAnchor.constraint(equalTo: Titleview.centerXAnchor).isActive = true
dayLbl.centerYAnchor.constraint(equalTo: Titleview.centerYAnchor).isActive = true
}
}
#objc func btnClickASAPType() {
print("DayExt")
// self.overriderFunc()
}
#objc func btnClickAddress() {
print("AddressExt")
}
#objc func btnClickCart() {
print("CartExt")
}
#objc func btnClickMenu() {
print("MenuExt")
}
#objc func btnClickBack() {
print("backExt")
self.navigationController?.popViewController(animated: true)
}
}
calling setupNavigation Method in viewDidLoad
self.setupNavItems( self.navigationItem, day:"Today", address:"Jayanagar 4th Block", type: 1,isMenuBtn: false,isCart: true)

Center a UILabel of a UIView

I am currently trying to make a simple pop up, here I have a button, once it gets tapped.
It should show a simple view above it, I achieved the blue background, but I am not being able to add a label to it, and center the label to the blue popup
let width = (sender as! UIButton).frame.width
let y = (sender as! UIButton).frame.origin.y
let x = (sender as! UIButton).frame.origin.x
myView = UIView(frame: CGRect(x: x, y: y - 30, width:width, height: 30))
myView.backgroundColor = UIColor.blue
let label = UILabel()
label.text = (sender as! UIButton).titleLabel?.text
label.font = UIFont(name:"avenirNext-Meduim",size:20)
label.center = self.myView.center
myview.addSubview(label)
self.view.addSubview(myView)
UIView.animate(withDuration: 0.1, delay: 0.1, options: [], animations: {
self.myView.alpha = 0.0
}) { (finished: Bool) in
self.myView.isHidden = true
}
Try to set your label frame:
let label = UILabel(frame: CGRect(origin: .zero, size: yourLabelSize))
Instead of
label.center = self.myView.center
try
label.centerXAnchor.constraint(equalTo: myView.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: myView.centerYAnchor).isActive = true
after
myview.addSubview(label)
self.view.addSubview(myView)
My solution
let codedLabel:UILabel = UILabel()
codedLabel.frame = CGRect(x: myView.center.x, y: myView.center.y, width: 51, height: 30)
codedLabel.textAlignment = .center
codedLabel.text = "q"
codedLabel.numberOfLines = 1
codedLabel.textColor=UIColor.red
codedLabel.font=UIFont.systemFont(ofSize: 22)
codedLabel.backgroundColor=UIColor.lightGray
self.myView.addSubview(codedLabel)
codedLabel.translatesAutoresizingMaskIntoConstraints = false
codedLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true
codedLabel.widthAnchor.constraint(equalToConstant: 30).isActive = true
codedLabel.centerXAnchor.constraint(equalTo: codedLabel.superview!.centerXAnchor).isActive = true
codedLabel.centerYAnchor.constraint(equalTo: codedLabel.superview!.centerYAnchor).isActive = true
let headerView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: tableView.frame.width, height: 50))
let label = UILabel()
label.frame = CGRect.init(x: headerView.center.x-60, y:headerView.center.y-15, width: 120, height: 30)
label.textAlignment = .center
label.textColor = #colorLiteral(red: 0.1290470958, green: 0.2743584514, blue: 0.6418049335, alpha: 1)
label.font = UIFont(name: "Roboto-Bold", size: 15)
label.text = "11-12-2020"
headerView.addSubview(label)
headerView.backgroundColor = #colorLiteral(red: 0.9967060685, green: 0.9998621345, blue: 0.9997505546, alpha: 1)

Custom titleView changes location after push and pop new screen in stack

I'm trying to implement custom titleView for navigation controller with "title" and "description" labels. If I placed this titleView on first VC, it looks good. If I push second VC into navigation stack and pop it, location of the titleView is changed.
titleView's constraints:
titleLabel.translatesAutoresizingMaskIntoConstraints = false
descriptionLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
descriptionLabel.widthAnchor.constraint(equalTo: titleLabel.widthAnchor).isActive = true
titleLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
descriptionLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 2.0).isActive = true
In viewDidLoad of VC I use follow code to insert titleView:
navigationItem.titleView = BarTitleView()
navigationItem.titleView?.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)
navigationItem.titleView?.updateConstraints()
I tried to insert follow lines into viewWillAppear (second VC has different bar buttons and it can be root of problem), but nothing changes
navigationItem.titleView?.bounds = CGRect(x: 0, y: 0, width: view.bounds.width, height: 44)
navigationItem.titleView?.updateConstraints()
How can I fixed this issue?
I have created a Title and Subtitle in the Navigation bar without the need for Interface Builder and constraint modification.
My Function to create the title view looks as follows:
class func setTitle(title:String, subtitle:String) -> UIView {
let titleLabel = UILabel(frame: CGRect(x: 0, y: -8, width: 0, height: 0))
titleLabel.backgroundColor = UIColor.clear
titleLabel.textColor = UIColor.white
titleLabel.font = UIFont.boldSystemFont(ofSize: 17)
titleLabel.text = title
titleLabel.sizeToFit()
let subtitleLabel = UILabel(frame: CGRect(x: 0, y: 12, width: 0, height: 0))
subtitleLabel.backgroundColor = UIColor.clear
subtitleLabel.textColor = UIColor.white
subtitleLabel.font = UIFont.systemFont(ofSize: 12)
subtitleLabel.text = subtitle
subtitleLabel.sizeToFit()
// Fix incorrect width bug
if (subtitleLabel.frame.size.width > titleLabel.frame.size.width) {
var titleFrame = titleLabel.frame
titleFrame.size.width = subtitleLabel.frame.size.width
titleLabel.frame = titleFrame
titleLabel.textAlignment = .center
}
let titleView = UIView(frame: CGRect(x: 0, y: 0, width: titleLabel.frame.size.width, height: titleLabel.frame.size.height))
titleView.addSubview(titleLabel)
titleView.addSubview(subtitleLabel)
let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width
if widthDiff < 0 {
let newX = widthDiff / 2
subtitleLabel.frame.origin.x = abs(newX)
} else {
let newX = widthDiff / 2
titleLabel.frame.origin.x = newX
}
return titleView
}
Then to use the title view in any view controller I just call this line:
self.navigationItem.titleView = Functions.Views.setTitle(title: "Title String", subtitle: "Subtitle String")

Resources