简体   繁体   中英

UIScrollView not scrolling in modal, Swift

I am working on a project in which I have to display a ViewController modally, however, the scrollview does not seem to work properly. It does not scroll. Instead of directly adding to scrollview, I added a view inside the scrollview which then I would add my data to. I checked that the contentsize of scrollview is much larger than the actual width of the scrollview, but yet, it does not scroll. I disabled auto-layout and nothing changes. Here is my code.

import Foundation
import UIKit

class VenueViewController: UIViewController, UIScrollViewDelegate{

    static var marker : Marker = Marker(v: "Error", lat: 1, lon: 1, az: 1, dist: 1000)

    @IBOutlet weak var viewInsideScrollView: UIView!
    @IBOutlet weak var dropDownView: UIView!
    @IBOutlet weak var upcomingEventLabel: UILabel!
    @IBOutlet var backgroundView: UIView!
    @IBOutlet weak var venueNameLabel: UILabel!
    @IBOutlet weak var currentEventLabel: UILabel!
    @IBOutlet weak var upcomingEventScrollView: UIScrollView!
    @IBOutlet weak var currentEventImageView: UIImageView!


    override func viewWillAppear(_ animated: Bool){
        super.viewWillAppear(animated)
        upcomingEventScrollView.isScrollEnabled = true
        upcomingEventScrollView.showsVerticalScrollIndicator = true
        upcomingEventScrollView.isUserInteractionEnabled = true
        upcomingEventScrollView.isPagingEnabled = true
        dropDownView.isUserInteractionEnabled = true

        if VenueViewController.marker.getVenueName() == "Error" {
            return
        }


        if !UIAccessibilityIsReduceTransparencyEnabled() {
            self.backgroundView.backgroundColor = UIColor.clear
            self.backgroundView.layer.zPosition = 0
            self.dropDownView.layer.zPosition = 1
            let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
            let blurEffectView = UIVisualEffectView(effect: blurEffect)
            blurEffectView.frame = self.backgroundView.bounds
            blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            self.backgroundView.addSubview(blurEffectView)
        } else {
            self.backgroundView.backgroundColor = UIColor.black
        }


        venueNameLabel.text = VenueViewController.marker.getVenueName()
        currentEventLabel.text = VenueViewController.marker.getEvents()[0].getName()
        ArtemisHelper.titleImageLoadView(imageView: currentEventImageView, event: VenueViewController.marker.getEvents()[0])

        loadUpcomingEvents()
    }

    func loadUpcomingEvents(){
        for event in VenueViewController.marker.getEvents(){
            if event.getName() == currentEventLabel.text{
                //continue
            }
            let eventTitleLabel : UILabel = UILabel()
            eventTitleLabel.text=event.getName() + " " + event.getLocalDate()
            eventTitleLabel.frame.size.width = dropDownView.frame.width
            eventTitleLabel.frame.size.height = 20

            eventTitleLabel.frame = CGRect(x: self.viewInsideScrollView.frame.minX, y: self.viewInsideScrollView.bounds.minY, width: self.viewInsideScrollView.frame.width, height: eventTitleLabel.frame.size.height)

            eventTitleLabel.frame = eventTitleLabel.frame.offsetBy(dx: 0, dy: self.upcomingEventScrollView.contentSize.height)
            self.viewInsideScrollView.addSubview(eventTitleLabel)

            self.upcomingEventScrollView.contentSize = CGSize(width: self.upcomingEventScrollView.contentSize.width, height: self.upcomingEventScrollView.contentSize.height+eventTitleLabel.frame.height)
            self.viewInsideScrollView.frame = CGRect(x: self.upcomingEventScrollView.bounds.minX, y: self.upcomingEventScrollView.bounds.minY, width: self.upcomingEventScrollView.frame.width, height: self.upcomingEventScrollView.contentSize.height)

        }
        print(self.viewInsideScrollView.frame.height)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch : UITouch = touches.first!
        let touchLocation = touch.location(in: self.view)
        let obstacleViewFrame = self.view.convert(dropDownView.frame, from: dropDownView.superview)

        if !obstacleViewFrame.contains(touchLocation) {
            self.dismiss(animated: true, completion: nil)
        }
    }
}

从主故事板

There are many advantages to using constraints and auto-layout, but you certainly can do what you want without it.

Your "add labels and set frames" loop is very convoluted. Take a look at this approach:

func loadUpcomingEvents(){

    // this is our starting Label frame
    //  at 0,0 and dropDownViewWidth x 20 height
    var labelRect = CGRect(x: 0, y: 0, width: dropDownView.frame.width, height: 20)

    for event in VenueViewController.marker.getEvents(){

        // instantiate a new label, using the current labelRect for the frame
        let eventTitleLabel : UILabel = UILabel(frame: labelRect)

        // set the text of the label
        eventTitleLabel.text=event.getName() + " " + event.getLocalDate()

        // add the label to the "inside" view
        self.viewInsideScrollView.addSubview(eventTitleLabel)

        // increment the Y position of labelRect by the Height of labelRect
        labelRect.origin.y += labelRect.size.height

    }

    // labelRect is now the frame of the "next label" in the list, 
    //  if there was a next label,
    //  so we can use its Y position for the Height of the "inside" view
    viewInsideScrollView.frame = CGRect(x: 0, y: 0, width: dropDownView.frame.width, height: labelRect.origin.y)

    // and, we set the scroll view's contentSize to the size of the "inside" view
    upcomingEventScrollView.contentSize = viewInsideScrollView.frame.size
}

After taking apart the code piece by piece, I found out that DonMag was right in the sense that there was a transparent view that was covering the scrollview.

    self.backgroundView.addSubview(blurEffectView)

Here, when I add the subview, this ends up covering the scrollview even though I set the zPosition to something lower than the scrollview. I added a view adjacent to backgroundView and added the blur effect view to that, which allowed me to still access the scrollview.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM