Custom resuable UIActivityIndicatorView Class programmatically - ios

I'm new in making views programmatically.
I'm trying to make UIActivityIndicatorView class to make it reusable for me.
This is the class I made:
class ActivityIndicator: UIActivityIndicatorView {
let indicator = UIActivityIndicatorView()
let indicatorContainer = UIView()
func setupIndicatorView() {
indicatorContainer.isHidden = false
indicator.isHidden = false
indicator.style = .large
indicator.color = .white
indicator.startAnimating()
indicator.hidesWhenStopped = true
indicator.translatesAutoresizingMaskIntoConstraints = false
indicatorContainer.backgroundColor = .darkGray
indicatorContainer.alpha = 0.7
indicatorContainer.layer.cornerRadius = 8.0
indicatorContainer.translatesAutoresizingMaskIntoConstraints = false
addSubview(indicatorContainer)
indicatorContainer.addSubview(indicator)
func setupIndicatorContainerConstraints() {
NSLayoutConstraint.activate([
indicatorContainer.centerXAnchor.constraint(equalTo: centerXAnchor),
indicatorContainer.centerYAnchor.constraint(equalTo: centerYAnchor),
indicatorContainer.widthAnchor.constraint(equalToConstant: frame.width / 5),
indicatorContainer.heightAnchor.constraint(equalToConstant: frame.width / 5)
])
}
func setupIndicatorViewConstraints() {
NSLayoutConstraint.activate([
indicator.centerXAnchor.constraint(equalTo: indicatorContainer.centerXAnchor),
indicator.centerYAnchor.constraint(equalTo: indicatorContainer.centerYAnchor)
])
}
setupIndicatorContainerConstraints()
setupIndicatorViewConstraints()
}
func hideIndicatorView() {
indicatorContainer.isHidden = true
indicator.stopAnimating()
indicator.isHidden = true
indicatorContainer.removeFromSuperview()
indicator.removeFromSuperview()
}
}
When I'm trying to make an instance from this class, it doesn't work in any other controller. Like this:
class SignInViewController: UIViewController {
let indicator = ActivityIndicator()
lazy var mainView: SignInView = {
let view = SignInView(delegate: self, frame: self.view.frame)
view.backgroundColor = .white
return view
}()
override func loadView() {
super.loadView()
view = mainView
}
func loginButtonTapped() {
indicator.setupIndicatorView()
}
}
I searched a lot to understand how to make it work but I haven't found a way.

You don't add it to vc's view
indicator.setupIndicatorView()
so consider
setupIndicatorView(_ view:UIView) {
.....
.....
// add it here
addSubview(indicatorContainer)
indicatorContainer.addSubview(indicator)
view.addSubview(self)
}

Related

What error am I making when trying to pass data between ViewControllers using closures?

My main View Controller has an embedded UITabbarController in it. There are 2 subVCs: viewControllerONE & viewControllerTWO.
viewControllerONE displays a label showing the user's current score, and viewControllerTWO displays a button, pressing which should display an error window on viewControllerONE.
(For the sake of simplicity, the user has to manually navigate to viewControllerONE using the tab bar to see the error, ie, pressing the button on viewControllerTWO doesn't take you to viewControllerONE and then display the errorWindow.)
The error window is a simple UIView class.
From SO, I have learnt that the best way to pass data in swift isn't delegates but closures, as the former is more of an objective C design, and so I've used closures to pass data between view controllers.
So here is my viewControllerONE code:
class ViewControllerONE: UIViewController {
var score = 10
lazy var scoreLabel: UILabel = {
let label = UILabel()
label.text = String(score)
label.font = .systemFont(ofSize: 80)
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(scoreLabel)
let VC = ViewControllerTWO()
VC.callback = { [weak self ] in
let error = errorView()
self?.view.addSubview(error)
}
NSLayoutConstraint.activate([
scoreLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
scoreLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
}
}
and here is my viewControllerTWO code:
class ViewControllerTWO: UIViewController {
var callback: (() -> Void)?
let buttonTwo: UIButton = {
let button = UIButton()
button.setTitle("HIT THIS BUTTON!", for: .normal)
button.backgroundColor = .systemBlue
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(buttonTwoPressed), for: .touchUpInside)
button.layer.cornerRadius = 8
return button
}()
#objc func buttonTwoPressed() {
print("PRESSEDDDD")
callback?()
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(buttonTwo)
NSLayoutConstraint.activate([
buttonTwo.centerXAnchor.constraint(equalTo: view.centerXAnchor),
buttonTwo.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
}
And here is the error view:
class ErrorView: UIView {
fileprivate let dismissButton: UIButton = {
let button = UIButton()
button.setTitle("DISMISS!!!!", for: .normal)
button.backgroundColor = .systemBlue
button.translatesAutoresizingMaskIntoConstraints = false
button.addTarget(self, action: #selector(dismissButtonPressed), for: .touchUpInside)
button.layer.cornerRadius = 12
return button
}()
#objc func dismissButtonPressed() {
self.errorGoAway()
}
fileprivate let errorViewBox: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
v.layer.cornerRadius = 24
return v
}()
#objc fileprivate func errorGoAway() {
self.alpha = 0
}
#objc fileprivate func errorShow() {
self.alpha = 1
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(errorGoAway)))
self.backgroundColor = UIColor.gray
self.backgroundColor?.withAlphaComponent(0.8)
self.frame = UIScreen.main.bounds
self.addSubview(errorViewBox)
errorViewBox.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
errorViewBox.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
errorViewBox.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.7).isActive = true
errorViewBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.45).isActive = true
errorViewBox.addSubview(dismissButton)
dismissButton.leadingAnchor.constraint(equalTo: errorViewBox.leadingAnchor).isActive = true
dismissButton.trailingAnchor.constraint(equalTo: errorViewBox.trailingAnchor).isActive = true
dismissButton.centerYAnchor.constraint(equalTo: errorViewBox.centerYAnchor).isActive = true
dismissButton.heightAnchor.constraint(equalTo: errorViewBox.heightAnchor, multiplier: 0.15).isActive = true
errorShow()
}
You need to get your controller from tabBarController instead of create new instance:
class ViewControllerONE: UIViewController {
var score = 10
lazy var scoreLabel: UILabel = {
let label = UILabel()
label.text = String(score)
label.font = .systemFont(ofSize: 80)
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
label.textColor = .blue
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(scoreLabel)
var VC: ViewControllerTWO?
let arrayOfVC = self.tabBarController?.viewControllers ?? []
for item in arrayOfVC {
if let secondVC = item as? ViewControllerTWO {
VC = secondVC
break
}
}
VC?.callback = { [weak self ] in
let error = ErrorView()
self?.view.addSubview(error)
}
NSLayoutConstraint.activate([
scoreLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
scoreLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
])
}
}

UIViewController Subclass does not recognize UITapGesture

With the intention to slim down my viewcontroller a little bit, i want to move the ui elements and corresponding functions into a subclass. but then my gestures don't work. how can i solve this?
MyViewController.swift
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
SubclassMyViewController().setupUserInterface(view: view)
}
#objc func doSomething() {
log.info("logo was tapped")
}
}
SubclassMyViewController.swift
class SubclassMyViewController: MyViewController {
func setupUserInterface(view: UIView) {
// ...
view.addSubview(logoImage)
logoImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
logoImage.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
logoImage.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
}
lazy var logoImage: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "logo")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
// ADD GESTURE
let tap = UITapGestureRecognizer(target: self, action: #selector(doSomething))
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tap)
return imageView
}()
}
Putting everything into the Viewcontroller does work. if I split it in two classes, the gesture won't be recognized.. Thanks!
I think you're confusing some things here.
SubclassMyViewController().setupUserInterface(view: view) this line creates an instance of SubclassMyViewController, which in your code sample owns the image view. Because you don't have any references to the created subclass however, it will die as soon as this line is done executing.
You could accomplish your goal by creating a static helper class instead. Here's how that would look.
class MyViewController: UIViewController {
var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
MyViewControllerSetupHelper.setupUserInterface(viewController: self)
}
#objc func doSomething() {
log.info("logo was tapped")
}
}
class MyViewControllerSetupHelper {
static func setupUserInterface(viewController: MyViewController) {
let view = viewController.view!
let imageView = getLogoImageView()
viewController.imageView = imageView
let tapGesture = UITapGestureRecognizer(target: viewController, action: #selector(MyViewController.doSomething))
imageView.addGestureRecognizer(tapGesture)
view.addSubview(imageView)
NSLayoutConstraint.activate([
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
imageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
imageView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5)
])
}
static func getLogoImageView() -> UIImageView {
let imageView = UIImageView()
imageView.image = UIImage(named: "logo")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
imageView.isUserInteractionEnabled = true
return imageView
}
}
SubclassMyViewController().setupUserInterface(view: view) is creating a new instance of subclass, but the reference of the instance is not stored.
Swift will deallocate the class if there is no reference (refer to ARC).
The lazy var logoImage is adding a GestureRecognizer which points to the doSomething() of the SubclassMyViewController-instance, which is deallocated immediately.
It would work if you do this (THIS IS NOT GOOD):
class ViewController: UIViewController {
var x: SubclassMyViewController!
override func viewDidLoad() {
super.viewDidLoad()
x = SubclassMyViewController()
x.setupUserInterface(view: view)
}
#objc func doSomething() {
log.info("logo was tapped")
}
}
You should fix your design, because:
ViewController is accessing SubclassMyViewController, which is, however, a subclass of ViewController
You doing really strange things. Gesture recognizer added to SubclassMyViewController instance. Which seams removed after creation.
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
SubclassMyViewController().setupUserInterface(view: view, vc: self)
}
#objc func doSomething() {
log.info("logo was tapped")
}
}
class SubclassMyViewController: MyViewController {
func setupUserInterface(view: UIView, vc: UIViewController) {
// ...
view.addSubview(logoImage)
logoImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
logoImage.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
logoImage.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
let tap = UITapGestureRecognizer(target: vc, action: #selector(doSomething))
logoImage.isUserInteractionEnabled = true
logoImage.addGestureRecognizer(tap)
}
lazy var logoImage: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "logo")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
return imageView
}()
}
P.S. code is really dirty.. don't do like this
Edit
Probably this is what you wanna do:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
SubclassMyViewController().setupUserInterface(view: view, vc: self)
}
#objc func doSomething() {
log.info("logo was tapped")
}
func setupUserInterface(view: UIView) {
// ...
view.addSubview(logoImage)
logoImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
logoImage.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
logoImage.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true
let tap = UITapGestureRecognizer(target: self, action: #selector(doSomething))
logoImage.isUserInteractionEnabled = true
logoImage.addGestureRecognizer(tap)
}
lazy var logoImage: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "logo")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
return imageView
}()
}

my question is about tap gesture.that is not working

class menuView
{
let View = UIView()
let resignView = UIView()
let tap = UITapGestureRecognizer()
func makeView(view:UIView){
makeResignView(view: view)
view.addSubview(View)
View.translatesAutoresizingMaskIntoConstraints = false
View.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
View.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
View.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
View.widthAnchor.constraint(equalToConstant: view.frame.width - 100).isActive = true
View.backgroundColor = UIColor.cyan
}
func makeResignView(view:UIView){
print("resing view is activate")
resignView.frame = view.frame
view.addSubview(resignView)
resignView.backgroundColor = UIColor.blue
resignView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(handleDismiss(recog:)))
resignView.addGestureRecognizer(tap)
}
#objc func handleDismiss(recog:UITapGestureRecognizer){
print("rsing view is dismiss")
View.removeFromSuperview()
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.gray
}
#IBAction func PlaceView(_ sender: Any) {
let NewView = menuView()
NewView.resignView.frame = view.frame
NewView.makeResignView(view: self.view)
NewView.makeView(view: self.view)
}
}
gesture is not working.
In the menuView class i make a view and add a gesture to it .In the viewController class i add the menuView and run the code.the view is added but the gesture is not working.
The correct way should have been to inherit subview with UIView class.
See below example -
override func viewDidLoad() {
super.viewDidLoad()
let newView = subView()
newView.addGuesture()
self.view.addSubview(newView)
// Do any additional setup after loading the view, typically from a nib.
}
class subView:UIView{
func addGuesture(){
let tap = UITapGestureRecognizer()
tap.addTarget(self,action:#selector(handleTap))
self.isUserInteractionEnabled = true
self.addGestureRecognizer(tap)
self.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
self.backgroundColor = UIColor.red;
}
#objc func handleTap(){
print("tap is working")
}
}

call label postion and size from outside of class (Swift4)

What I am trying to do is assign the position and size of a label from outside a class. Then within 2 separate classes call the label to add text to it. This would save time a lot of time if this would work.
let backbutton = UILabel!
backbutton.translatesAutoresizingMaskIntoConstraints = false
backbutton.leftAnchor.constraint(equalTo: _, constant: 20).isActive = true
backbutton.topAnchor.constraint(equalTo: _, constant: 125).isActive = true
backbutton.widthAnchor.constraint(equalToConstant: 50).isActive = true
backbutton.heightAnchor.constraint(equalToConstant: 50).isActive = true
class nineViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
backbutton.text = String("red")
}
}
class two: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
backbutton.text = String("two")
}
}
Create a Utilities class separately to use the functions that are inside it globally.
Utilities:
class Utilities: NSObject
{
class func createLabel(on view: UIView, horizontalAnchors hAnchors: (leading: CGFloat, leadingView: UIView, trailing: CGFloat, trailingView: UIView), verticalAnchors vAnchors: (top: CGFloat, topView: UIView, bottom: CGFloat, bottomView: UIView)) -> UILabel {
let label = UILabel()
view.addSubview(label)
label.backgroundColor = UIColor.red
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: hAnchors.leadingView.leadingAnchor, constant: hAnchors.leading).isActive = true
label.trailingAnchor.constraint(equalTo: hAnchors.trailingView.trailingAnchor, constant: -hAnchors.trailing).isActive = true
label.topAnchor.constraint(equalTo: vAnchors.topView.topAnchor, constant: vAnchors.top).isActive = true
label.bottomAnchor.constraint(equalTo: vAnchors.bottomView.topAnchor, constant: -vAnchors.bottom).isActive = true
return label
}
class func createLabel(on view: UIView, positionAnchors pAnchors: (leading: CGFloat, leadingView: UIView, top: CGFloat, topView: UIView), size: (width: CGFloat, height: CGFloat)) -> UILabel {
let label = UILabel()
view.addSubview(label)
label.backgroundColor = UIColor.red
label.translatesAutoresizingMaskIntoConstraints = false
label.leadingAnchor.constraint(equalTo: pAnchors.leadingView.leadingAnchor, constant: pAnchors.leading).isActive = true
label.topAnchor.constraint(equalTo: pAnchors.topView.topAnchor, constant: pAnchors.top).isActive = true
label.widthAnchor.constraint(equalToConstant: size.width).isActive = true
label.heightAnchor.constraint(equalToConstant: size.height).isActive = true
return label
}
}
In ViewController:
#IBOutlet weak var autoLayedoutLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let originY: CGFloat = 50
let spacing: CGFloat = 16
let width: CGFloat = 300
let height: CGFloat = 50
let label = Utilities.createLabel(on: view, positionAnchors: (spacing, view, originY, view), size: (width, height))
label.text = "Label with Position Anchors & Size"
label.backgroundColor = UIColor.red
let label2 = Utilities.createLabel(on: view, horizontalAnchors: (spacing, view, spacing, view), verticalAnchors: (spacing + height, label, spacing, autoLayedoutLabel))
label2.text = "Label with Horizontal & Vertical Anchors"
label2.backgroundColor = UIColor.green
}
You can have different variable for buttonText and set his position and size in his setter like
var buttonText:String {
didSet{
backButton.text = buttonText
setFontAndPosition()
}
}
and in viewController just set the value
override func viewDidLoad() {
super.viewDidLoad()
buttonText = "red"
}
I found it's feasible to directly use global UILable. If you don't need to manage too many labels, this is the simplest way.
A TabBarcontroller is used for testing here.
let backbutton = UILabel()
class MyTabBarController : UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
setViewControllers([SettingViewController(), NineViewController(), TwoViewController()], animated: false)
}
}
class SettingViewController: UIViewController {
override var tabBarItem: UITabBarItem!{
get {
return UITabBarItem.init(title: "setting", image: nil, tag: 0)
}
set{
super.tabBarItem = newValue
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.view.addSubview(backbutton)
backbutton.text = "cool"
backbutton.translatesAutoresizingMaskIntoConstraints = false
backbutton.leftAnchor.constraint(equalTo: self.view.leftAnchor, constant: 20).isActive = true
backbutton.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 125).isActive = true
backbutton.widthAnchor.constraint(equalToConstant: 50).isActive = true
backbutton.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
}
class NineViewController: UIViewController {
override var tabBarItem: UITabBarItem!{
get {
return UITabBarItem.init(title: "nine", image: nil, tag: 0)
}
set{
super.tabBarItem = newValue
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
backbutton.text = String("red")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
backbutton.text = String("red-Appear")
}
}
class TwoViewController: UIViewController {
override var tabBarItem: UITabBarItem!{
get {
return UITabBarItem.init(title: "two", image: nil, tag: 0)
}
set{
super.tabBarItem = newValue
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
backbutton.text = String("two")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
backbutton.text = String("two-Appear")
}
}
If you prefer defining the label inside one class. You may define the global UILabel as this:
weak var backbutton: UILabel!
class SettingViewController: UIViewController {
let mybutton = UILabel()
backbutton = mybutton
// continue
}
You don't need to change any other codes.
Now is the second part of the story. If you wanna setup a global UILabel outside any view, is that possible. Without constraints it's very simple like this:
let backbutton: UILabel! = {
let button = UILabel()
button.text = "test"
button.frame = CGRect.init(x: 200, y: 200, width: 50, height: 50)
return button
}()
The setting View changes like this :
class SettingViewController: UIViewController {
override var tabBarItem: UITabBarItem!{
get {
return UITabBarItem.init(title: "setting", image: nil, tag: 0)
}
set{
super.tabBarItem = newValue
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.white
self.view.addSubview(backbutton)
}
}
It's clear there is only one line in the SettingVC. But if you need to use constraints, what should we do? Everything else is fine, but the position of UILabel constraints depends on the superView of UILabel. So an extension can be used here to make things easier.
let specialLabelTag = 1001
let backbutton: UILabel! = {
let button = UILabel()
button.tag = specialLabelTag
button.text = "test" // for test purpose
button.translatesAutoresizingMaskIntoConstraints = false
button.widthAnchor.constraint(equalToConstant: 50).isActive = true
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
return button
}()
extension UILabel{
override open func didMoveToSuperview() {
superview?.didMoveToSuperview()
if(tag == specialLabelTag){
leftAnchor.constraint(equalTo: superview!.leftAnchor, constant: 20).isActive = true
topAnchor.constraint(equalTo: superview!.topAnchor, constant: 125).isActive = true
}
}
The tag used in extension is to identify the global UILabel in order not to affect other UILabels. Only position constraints are needed in the extension. SettingUP vc is as same as before.
Now you can build a label without any view class. But you have to add them somewhere and modify the text as you like. Hope this is the answer to the question.
BTW, you can subclass the UILabel to MyUILabel with above code and then make it global (just put outside any class). It would be much easier because you don't need to use specialLabelTag.
let backbutton = MyUILabel()

UIScrollView didn't scrolling?

I'm creating a UIScrollView from code.The only problem is the scrolling is not working go through lot's of the post but didn't find anything.
Here is my code Any help greatly Appreciated.
class ShopDetailviewController : UIViewController {
var MainScrollView : UIScrollView?
let viewForScrollview : UIView = {
let view = UIView()
view.backgroundColor = UIColor.darkGray
return view
}()
let shopNameandAddresView : UIView = {
let view = UIView()
view.backgroundColor = UIColor.black
return view
}()
let timePaymentDetail : UIView = {
let view = UIView()
view.backgroundColor = UIColor.blue
return view
}()
let shopImage : UIImageView = {
let shopeImage = UIImageView()
shopeImage.backgroundColor = UIColor.green
return shopeImage
}()
let ratingStarLable : UILabel = {
let ratingStratLable = UILabel()
ratingStratLable.backgroundColor = UIColor.red
ratingStratLable.text = "3.5"
return ratingStratLable
}()
let shopName : UILabel = {
let shopName = UILabel()
shopName.backgroundColor = UIColor.gray
shopName.text = "Kimling"
return shopName
}()
let shopLocation : UILabel = {
let shopLocation = UILabel()
shopLocation.backgroundColor = UIColor.white
shopLocation.text = "Kondhwa"
return shopLocation
}()
let seprater : UIView = {
let seprater = UIView()
seprater.backgroundColor = UIColor.white
return seprater
}()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
navigationController?.navigationBar.tintColor = .white
view.backgroundColor = UIColor.white
}
override func viewDidLoad() {
super.viewDidLoad()
MainScrollView = UIScrollView()
MainScrollView?.isScrollEnabled = true
MainScrollView?.indicatorStyle = .default
MainScrollView?.contentSize = CGSize(width:self.view.bounds.width, height: 8000)
MainScrollView?.backgroundColor = UIColor.purple
setupViews()
}
func setupViews(){
view.addSubview(MainScrollView!)
MainScrollView?.addSubview(viewForScrollview)
viewForScrollview.addSubview(shopImage)
viewForScrollview.addSubview(shopNameandAddresView)
viewForScrollview.addSubview(timePaymentDetail)
addConstraintsWithFormat("H:|-0-[v0(414)]-0-|", views: MainScrollView!)
addConstraintsWithFormat("V:|-0-[v0(8000)]", views: MainScrollView!)
addConstraintsWithFormat("H:|-0-[v0(414)]-0-|", views: viewForScrollview)
addConstraintsWithFormat("V:|-0-[v0(8000)]", views: viewForScrollview)
addConstraintsWithFormat("V:|-0-[v0(1000)]-0-[v1(1000)]", views: shopImage,shopNameandAddresView)
addConstraintsWithFormat("H:|-0-[v0]-0-|", views: shopImage)
addConstraintsWithFormat("H:|-0-[v0]-0-|", views: shopNameandAddresView)
}
}
Use as this
override func viewDidLayoutSubviews()
{
MainScrollView?.contentSize = CGSize(width:self.view.bounds.width, height: 8000)
}
It seems like the in viewDidLoad layout is not finished so the scrollView wont scroll because it has no proper contentSize try setting the contentSize in ViewWillAppear as
MainScrollView?.contentSize = CGSize(width:self.view.bounds.width, height: 8000)

Resources