Swift - Как создать эффект формы пузыря - PullRequest
0 голосов
/ 19 сентября 2019

Итак, я пытаюсь создать следующий эффект с помощью xcode swift.

Я пытаюсь заново создать пузырь формы, который содержит текстовые поля и сами текстовые поля, в следующем стиле.

То, что я пробовал до сих пор:

Создание представления пользовательского интерфейса с изогнутыми границами с последующим использованием прозрачного текстового поля и UILabels для указания содержимого поля.

Я предполагаю, что это должно быть UItableview с учетом строки отступа, но я не уверен, как стилизовать табличное представление таким же образом.Я предположил, что могу использовать layer.cornerRadius, как и для UIView, но это, похоже, не работает.

Также весь контроллер представления является контроллером UItableview или UICollectionView?

Любая помощьо том, как создать форму, как показано ниже.

enter image description here

Ответы [ 3 ]

1 голос
/ 19 сентября 2019

Использование layer.cornerRadius для всей таблицы не будет работать.Вы должны использовать UITableviewController или обычный UIViewController, который содержит tableView, а затем разделить ваш просмотр таблицы на 3 раздела

  • Первый раздел должен быть профильным: нет сомнений в этом разделе, граничьте с вашей ячейкой,так же, как дизайн

  • Второй раздел должен быть личной информации.3 ячейки, каждая ячейка содержит текстовое поле.Вы можете вычислить и создать границу для ячейки по соответствующей позиции (верхняя ячейка будет окаймлена сверху слева и справа, нижняя ячейка будет окаймлена снизу слева и справа, в противном случае не будет окаймлена)

  • Третийраздел: без сомнения, только одна ячейка (смена аккаунта)

0 голосов
/ 19 сентября 2019

SWIFT Solution

Благодаря Пауло Силве

Шаг 1: Вы можетепросто создайте файл swift с именем «CUIView» (или по собственному желанию) и используйте следующий код IBDesignable внутри него и сохраните.

//
//  CUIView.swift
//  CustomUIView
//
//  Created by Paulo Silva on 23/08/2019.
//  Copyright © 2019 example. All rights reserved.
//

import UIKit
import UIKit
import CoreGraphics

@IBDesignable class CUIView: UIView {

    // MARK: - Private Variables -

    private let containerView = UIView()
    private var containerImageView = UIImageView()

    // MARK: - Public Attributes -

    @IBInspectable public var backgroundImage: UIImage? {
        get {
            return self.containerImageView.image
        }
        set {
//            addShadowColorFromBackgroundImage()
            self.containerImageView.image = newValue
        }
    }

    override open var backgroundColor: UIColor? {
        didSet(new) {
            if let color = new {
                containerView.backgroundColor = color
            }
            if backgroundColor != UIColor.clear { backgroundColor = UIColor.clear }
        }
    }

    @IBInspectable var borderColor: UIColor {
        get {
            return UIColor(cgColor: self.containerView.layer.borderColor!)
        }
        set {
            self.layer.borderColor = newValue.cgColor
            self.containerView.layer.borderColor = newValue.cgColor
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return self.containerView.layer.borderWidth
        }
        set {
            self.layer.borderWidth = newValue
            self.containerView.layer.borderWidth = newValue
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return self.containerView.layer.cornerRadius
        }
        set {
            self.layer.cornerRadius = newValue
            self.containerView.layer.cornerRadius = newValue
        }
    }

    @IBInspectable var shadowOpacity: Float {
        get {
            return self.layer.shadowOpacity
        }
        set {
            self.layer.shadowOpacity = newValue
        }
    }

    @IBInspectable var shadowRadius: CGFloat {
        get {
            return self.layer.shadowRadius
        }
        set {
            self.layer.shadowRadius = newValue
        }
    }

    @IBInspectable var shadowOffset: CGSize {
        get {
            return self.layer.shadowOffset
        }
        set {
            self.layer.shadowOffset = newValue
        }
    }

    @IBInspectable var shadowColor: UIColor {
        get {
            return UIColor(cgColor: self.layer.shadowColor!)
        }
        set {
            self.layer.shadowColor = newValue.cgColor
        }
    }

//    @IBInspectable var shadowColorFormImage: Bool = false {
//        didSet {
//            addShadowColorFromBackgroundImage()
//        }
//    }

    // MARK: - Life Cycle -

    override init(frame: CGRect) {
        super.init(frame: frame)
        addViewLayoutSubViews()
        refreshViewLayout()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        addViewLayoutSubViews()
        refreshViewLayout()
    }

    override open func draw(_ rect: CGRect) {
        super.draw(rect)
        refreshViewLayout()
//        addShadowColorFromBackgroundImage()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        refreshViewLayout()
//        addShadowColorFromBackgroundImage()
    }

    // MARK: - Private Methods -

    private func refreshViewLayout() {
        // View
        self.clipsToBounds = true
        self.layer.masksToBounds = false
        self.layer.cornerRadius = cornerRadius

        // Shadow
        self.layer.shadowOpacity = shadowOpacity
        self.layer.shadowColor = shadowColor.cgColor
        self.layer.shadowOffset = shadowOffset
        self.layer.shadowRadius = shadowRadius

        // Container View
        self.containerView.layer.masksToBounds = true
        self.containerView.layer.cornerRadius = cornerRadius

        // Image View
        self.containerImageView.backgroundColor = UIColor.clear
        self.containerImageView.image = backgroundImage
        self.containerImageView.layer.cornerRadius = cornerRadius
        self.containerImageView.layer.masksToBounds = true
        self.containerImageView.clipsToBounds = true
        self.containerImageView.contentMode = .redraw
    }

    private func addViewLayoutSubViews() {
        // add subViews
        self.addSubview(self.containerView)
        self.containerView.addSubview(self.containerImageView)

        // add image constraints
        self.containerImageView.translatesAutoresizingMaskIntoConstraints = false
        self.containerImageView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        self.containerImageView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        self.containerImageView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        self.containerImageView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

        // add view constraints
        self.containerView.translatesAutoresizingMaskIntoConstraints = false
        self.containerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        self.containerView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        self.containerView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        self.containerView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }

//    private func addShadowColorFromBackgroundImage() {
//        // Get the averageColor from the image for set the Shadow Color
//        if shadowColorFormImage {
//            let week = self
//            DispatchQueue.main.async {
//                week.shadowColor = (week.containerImageView.image?.averageColor)!
//            }
//        }
//    }
}

extension UIImage {

    static func imageWithColor(tintColor: UIColor) -> UIImage {
        let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        tintColor.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }

    func withBackground(color: UIColor, opaque: Bool = true) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
        guard let ctx = UIGraphicsGetCurrentContext() else { return self }
        defer { UIGraphicsEndImageContext() }
        let rect = CGRect(origin: .zero, size: size)
        ctx.setFillColor(color.cgColor)
        ctx.fill(rect)
        ctx.concatenate(CGAffineTransform(a: 1, b: 0, c: 0, d: -1, tx: 0, ty: size.height))
        ctx.draw(cgImage!, in: rect)
        return UIGraphicsGetImageFromCurrentImageContext() ?? self
    }

    var averageColor: UIColor? {
        guard let inputImage = CIImage(image: self) else { return nil }
        let extentVector = CIVector(x: inputImage.extent.origin.x, y: inputImage.extent.origin.y, z: inputImage.extent.size.width, w: inputImage.extent.size.height)

        guard let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: inputImage, kCIInputExtentKey: extentVector]) else { return nil }
        guard let outputImage = filter.outputImage else { return nil }

        var bitmap = [UInt8](repeating: 0, count: 4)
        let context = CIContext(options: [.workingColorSpace: kCFNull as Any])
        context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil)

        return UIColor(red: CGFloat(bitmap[0]) / 255, green: CGFloat(bitmap[1]) / 255, blue: CGFloat(bitmap[2]) / 255, alpha: CGFloat(bitmap[3]) / 255)
    }
}

extension NSLayoutConstraint {
    func constraintWithMultiplier(_ multiplier: CGFloat) -> NSLayoutConstraint {
        return NSLayoutConstraint(item: self.firstItem!, attribute: self.firstAttribute, relatedBy: self.relation, toItem: self.secondItem, attribute: self.secondAttribute, multiplier: multiplier, constant: self.constant)
    }
}

extension UIScreen {

    enum SizeType: CGFloat {
        case unknown = 0.0
        case iPhone4 = 960.0
        case iPhone5 = 1136.0
        case iPhone6 = 1334.0
        case iPhone6Plus = 1920.0
    }

    var sizeType: SizeType {
        let height = nativeBounds.height
        guard let sizeType = SizeType(rawValue: height) else { return .unknown }
        return sizeType
    }
}

Шаг 2: Подключите связанный класс представления как 'CUIView' как следующее изображение

enter image description here

Шаг 3: Укажите радиус угла и установите фон, как показано на рисунке.

enter image description here

Для всех групп textField и textfieldВы можете использовать представление как родительское представление и связанный класс, чтобы получить этот результат.Для подчеркивания вы можете использовать простой вид с минимальной высотой, чтобы получить желаемый дизайн.

0 голосов
/ 19 сентября 2019

В iOS 13 вы можете просто установить стиль на Inset Grouped, и UITableView выглядит именно так - никаких дополнительных изменений не требуется.

...