Как разместить UIView поверх других UIView? - PullRequest
0 голосов
/ 31 мая 2018

Прямо сейчас у меня есть collectionView, для которого каждая ячейка содержит горизонтальный stackView.StackView заполняется серией UIViews (прямоугольников), по одному на каждый день месяца - каждая ячейка соответствует месяцу.Я заполняю представления стека следующим образом:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView == self.collectionView {
            ...
            return cell
        } else if collectionView == self.timeline {
            let index = indexPath.row
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "MMM"
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: timelineMonthCellReuseIdentifier, for: indexPath) as! SNTimelineMonthViewCell
            let firstPost = posts.first?.timeStamp
            let month = Calendar.current.date(byAdding: .month, value: index, to: firstPost!)
            print(dateFormatter.string(from: month!),dateFormatter.string(from: firstPost!),"month diff")
            for post in posts {
                print(post.timeStamp, "month diff")
            }
            cell.monthLabel.text = dateFormatter.string(from: month!)
            cell.monthLabel.textAlignment = .center

            if let start = month?.startOfMonth(), let end = month?.endOfMonth(), let stackView = cell.dayTicks {
                var date = start
                while date <= end {
                    let line = UIView()
                    if posts.contains(where: { Calendar.current.isDate(date, inSameDayAs: $0.timeStamp) }) {
                        line.backgroundColor = UIColor(red:0.15, green:0.67, blue:0.93, alpha:1.0)
                        let tapGuesture = UITapGestureRecognizer(target: self, action:  #selector (self.tapBar (_:)))
                        line.isUserInteractionEnabled = true
                        line.addGestureRecognizer(tapGuesture)
                        self.dayTicks[date] = line
                    } else {
                        line.backgroundColor = UIColor.clear
                    }
                    stackView.addArrangedSubview(line)
                    date = Calendar.current.date(byAdding: .day, value: 1, to: date)!
                }
            }
            return cell
        } else {
            preconditionFailure("Unknown collection view!")
        }
    }

Затем, когда пользователь прекращает прокручивать другое представление коллекции, я хочу добавить подпредставление arrowView поверх dayTick (посмотрите, как self.dayTicks заполняетсяподпредставления stackView выше).

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let currentIndex = self.collectionView.contentOffset.x / self.collectionView.frame.size.width
        let post = posts[Int(currentIndex)]
        for (_,tick) in self.dayTicks {
            tick.subviews.forEach({ $0.removeFromSuperview() })
        }
        let day = Calendar.current.startOfDay(for: post.timeStamp)
        let tick = self.dayTicks[day]
        let arrow = UIImage(named:"Tracer Pin")
        let arrowView = UIImageView(image: arrow)
//        arrowView.clipsToBounds = false
        print((tick?.frame.origin)!,"tick origin")
//        arrowView.frame.origin = (tick?.frame.origin)!
//        arrowView.frame.size.width = 100
//        arrowView.frame.size.height = 100
        tick?.addSubview(arrowView)

    }

Этот вид работ выглядит так:

enter image description here

Красный прямоугольник добавлен, но он отображается насправа от dayTick, и он выглядит как длинный тонкий прямоугольник.В действительности, изображение Tracer Pin, на которое ссылаются, выглядит так:

enter image description here

По крайней мере, откуда берется красный цвет, но, как вы можете видеть, он растягиваетсястранно и обрезает все, что не в прямоугольном пространстве UIView.

Теперь обратите внимание, что я закомментировал 4 строки, которые устанавливают размер и происхождение arrowView, а также устанавливают для clipToBounds значение false.Когда я раскомментирую эти строки - arrowView просто не появляется вообще, поэтому я, должно быть, поступаю неправильноЯ хочу показать что-то вроде этого:

enter image description here

Как я могу поставить это прямо сверху?

Ответы [ 3 ]

0 голосов
/ 31 мая 2018

Другая перспектива может состоять в том, чтобы сделать это с CALayer.Вот некоторые подсказки (вырезанные из другого проекта), которые помогут вам найти решение:

@IBInspectable open var slideIndicatorThickness: CGFloat = 5.0 {
    didSet {
        if slideIndicator != nil { slideIndicator.removeFromSuperlayer() }
        let slideLayer = CALayer()
        let theOrigin = CGPoint(x: bounds.origin.x, y: bounds.origin.y)
        let theSize = CGSize(width: CGFloat(3.0), height: CGFloat(10.0)
        slideLayer.frame = CGRect(origin: theOrigin, size: theSize)
        slideLayer.backgroundColor = UIColor.orange.cgColor
        slideIndicator = slideLayer
        layer.addSublayer(slideIndicator)
    }
}

fileprivate var slideIndicator: CALayer!

fileprivate func updateIndicator() {
    // ..
    // Somehow figure out new frame, based on stack view's frame.
    slideIndicator.frame.origin.x = newOrigin
}

Возможно, вам придется реализовать это на подклассе UIStackView или на вашем собственном пользовательском представлении, которое является оболочкой для UIStackView.

0 голосов
/ 03 июня 2018

Я закончил тем, что использовал CALayer - благодаря предложению @ ouni По какой-то причине CALayer, казалось, рисовал прямо поверх представления, а подпредставление - нет.Одним из ключей было снятие флажка «Прикрепить к границам» в самой ячейке collectionView (в отличие от подпредставления), чтобы я мог нарисовать расширенное основание стрелки вне ячейки представления коллекции:

enter image description here

Мой код выглядит следующим образом:

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        if scrollView == self.collectionView {
            print("is collection view")
            print(scrollView,"collection view")
            let currentIndex = self.collectionView.contentOffset.x / self.collectionView.frame.size.width
            let post = posts[Int(currentIndex)]
            for (_,tick) in self.dayTicks {
                tick.layer.sublayers = nil
            }
            let day = Calendar.current.startOfDay(for: post.timeStamp)
            let tick = self.dayTicks[day]
            let arrowLayer = CAShapeLayer()
            let path = UIBezierPath()
            let start_x = (tick?.bounds.origin.x)!
            let start_y = (tick?.bounds.minY)!
            let top_width = (tick?.bounds.width)!
            let tick_height = (tick?.bounds.height)!
            let tip_height = CGFloat(10)
            let tip_flare = CGFloat(10)
            path.move(to: CGPoint(x: start_x, y: start_y))
            path.addLine(to: CGPoint(x: start_x + top_width,y: start_y))
            path.addLine(to: CGPoint(x: start_x + top_width,y: start_y + tick_height))
            path.addLine(to: CGPoint(x: start_x + top_width + tip_flare,y: start_y+tick_height+tip_height))
            path.addLine(to: CGPoint(x: start_x - tip_flare,y: start_y + tick_height + tip_height))
            path.addLine(to: CGPoint(x: start_x,y: start_y+tick_height))
            path.close()
            arrowLayer.path = path.cgPath
            arrowLayer.fillColor = UIColor(red:0.99, green:0.13, blue:0.25, alpha:1.0).cgColor
            tick?.layer.addSublayer(arrowLayer)         
        } else {
            print(scrollView, "timeline collection view")
        }


    }

Это красиво рисует стрелку в верхней части подпредставления.

0 голосов
/ 31 мая 2018

Похоже, у вас фиксированная высота на arrowView.Может ли быть так, что часть красного треугольника находится под другим видом?

Иерархия представления отладки

Щелкните иерархию представления отладки, которая является вторым справа значком - это выглядит как3 прямоугольника.Проверьте, есть ли там все изображение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...