Подтвердить что ты не робот

Пользовательское оповещение (UIAlertView) с быстрым

Как создать пользовательское оповещение с помощью Swift? Я пытаюсь перевести руководство из Objective c, но загружает полноэкранный макет

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

    listaalertviewcontroller.view.backgroundColor = UIColor.clearColor()
    let purple = UIColor.purpleColor() // 1.0 alpha
    let semi = purple.colorWithAlphaComponent(0.5)

    listaalertviewcontroller.view.backgroundColor = semi


    presentingViewController.modalPresentationStyle = UIModalPresentationStyle.CurrentContext

    self.presentViewController(listaalertviewcontroller, animated: true, completion: nil)

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

4b9b3361

Ответ 1

Код, протестированный в Swift 5 и Xcode 10

Как сделать собственное оповещение

Я хотел сделать что-то подобное. Прежде всего, UIAlertView устарела в пользу UIAlertController. Посмотрите этот ответ для стандартного способа отображения предупреждения:

И UIAlertView, и UIAlertController на самом деле не допускают особых настроек. Одним из вариантов является использование стороннего кода. Однако я обнаружил, что создать собственное оповещение не так сложно, отобразив другой контроллер вида.

Пример здесь - только подтверждение концепции. Вы можете создать свое оповещение любым удобным для вас способом.

enter image description here

Раскадровка

У вас должно быть два контроллера просмотра. Ваш второй контроллер представления будет вашим предупреждением. Установите имя класса на AlertViewContoller и идентификатор раскадровки на alert. (Оба эти имени мы определили сами в приведенном ниже коде, ничего особенного в них нет. Сначала вы можете добавить код, если хотите. Возможно, будет проще, если вы сначала добавите код.)

enter image description here

Установите цвет фона для корневого представления (в контроллере представления предупреждений), чтобы очистить (или полупрозрачный черный цвет подходит для оповещения). Добавьте еще один UIView и отцентрируйте его с ограничениями. Используйте это в качестве фона оповещения и поместите все, что вы хотите внутри. Для моего примера я добавил UIButton.

enter image description here

Код

ViewController.swift

import UIKit
class ViewController: UIViewController {

    @IBAction func showAlertButtonTapped(_ sender: UIButton) {

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let myAlert = storyboard.instantiateViewController(withIdentifier: "alert")
        myAlert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
        myAlert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
        self.present(myAlert, animated: true, completion: nil)
    }
}

AlertViewController.swift

import UIKit
class AlertViewController: UIViewController {

    @IBAction func dismissButtonTapped(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }
}

Не забудьте подключить розетки.

Вы можете добавить прослушиватель событий onTouchUp в фоновом режиме, чтобы закрыть всплывающее окно, когда пользователь нажимает за его пределами.

Это. Вы должны быть в состоянии сделать любое предупреждение, которое вы можете себе представить сейчас. Нет необходимости в стороннем коде.

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

enter image description here

Другие варианты

Однако иногда нет необходимости изобретать велосипед. Я впечатлен сторонним проектом SDCAlertView (лицензия MIT). Он написан на Swift, но вы можете использовать его и в проектах Objective-C. Он предлагает широкий спектр удобного использования.

Ответ 2

Вот код Swift 3. Большое спасибо @Suragch за удивительный подход к созданию пользовательского AlertView.

ViewController.swift

import UIKit
class ViewController: UIViewController {

@IBAction func showAlertButtonTapped(sender: UIButton) {

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let myAlert = storyboard.instantiateViewController(withIdentifier: "storyboardID")
        myAlert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
        myAlert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
        self.present(myAlert, animated: true, completion: nil)

}

AlertViewController.swift

import UIKit
class AlertViewController: UIViewController {

    @IBAction func dismissButtonTapped(sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }
}

Чтобы сделать это немного интереснее или сделать эффект по умолчанию в iOS, вы можете добавить либо VisualEffectView, либо изменить цвет основного UIView на темный цвет и установить его альфа до 70%. Я предпочитаю второй подход, так как эффект размытия не такой гладкий, как тот, который имеет вид с 70 альфа.

Эффект с VisualEffectView:

введите описание изображения здесь

Эффект с использованием UIView с 70 Alpha:

введите описание изображения здесь

Ответ 3

Используйте https://github.com/shantaramk/Custom-Alert-View

Это легко реализовать. просто следуйте ниже шагов:

  1. Перетащите папку AlertView в каталог проекта

  2. Показать всплывающее окно AlertView

    func showUpdateProfilePopup(_ message: String) {
    let alertView = AlertView(title: AlertMessage.success, message: message, okButtonText: LocalizedStrings.okay, cancelButtonText: "") { (_, button) in
        if button == .other {
            self.navigationController?.popViewController(animated: true)
        }
    }
    alertView.show(animated: true)
    

    }

Ответ 4

В настоящее время предупреждение - это просто представленный контроллер представления. Вы можете написать представленный контроллер представления, который ведет себя подобно предупреждению - то есть он всплывает на экран и затемняет все, что за ним - но это ваш контроллер представления, и вы можете предоставить ему любой интерфейс, который вам нравится.

Для начала я написал проект github, который вы можете загрузить и запустить, а также изменить в соответствии с вашими потребностями.

Я покажу ключевую часть кода. Контроллер представления "alert" в своих инициализаторах устанавливает свой собственный стиль модального представления как custom и устанавливает переходящий делегат:

class CustomAlertViewController : UIViewController {
    let transitioner = CAVTransitioner()

    override init(nibName: String?, bundle: Bundle?) {
        super.init(nibName: nibName, bundle: bundle)
        self.modalPresentationStyle = .custom
        self.transitioningDelegate = self.transitioner
    }

    convenience init() {
        self.init(nibName:nil, bundle:nil)
    }

    required init?(coder: NSCoder) {
        fatalError("NSCoding not supported")
    }
}

Вся работа выполняется переходным делегатом:

class CAVTransitioner : NSObject, UIViewControllerTransitioningDelegate {
    func presentationController(
        forPresented presented: UIViewController,
        presenting: UIViewController?,
        source: UIViewController)
        -> UIPresentationController? {
            return MyPresentationController(
                presentedViewController: presented, presenting: presenting)
    }
}

class MyPresentationController : UIPresentationController {

    func decorateView(_ v:UIView) {
        // iOS 8 doesn't have this
//        v.layer.borderColor = UIColor.blue.cgColor
//        v.layer.borderWidth = 2
        v.layer.cornerRadius = 8

        let m1 = UIInterpolatingMotionEffect(
            keyPath:"center.x", type:.tiltAlongHorizontalAxis)
        m1.maximumRelativeValue = 10.0
        m1.minimumRelativeValue = -10.0
        let m2 = UIInterpolatingMotionEffect(
            keyPath:"center.y", type:.tiltAlongVerticalAxis)
        m2.maximumRelativeValue = 10.0
        m2.minimumRelativeValue = -10.0
        let g = UIMotionEffectGroup()
        g.motionEffects = [m1,m2]
        v.addMotionEffect(g)
    }

    override func presentationTransitionWillBegin() {
        self.decorateView(self.presentedView!)
        let vc = self.presentingViewController
        let v = vc.view!
        let con = self.containerView!
        let shadow = UIView(frame:con.bounds)
        shadow.backgroundColor = UIColor(white:0, alpha:0.4)
        shadow.alpha = 0
        con.insertSubview(shadow, at: 0)
        shadow.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        let tc = vc.transitionCoordinator!
        tc.animate(alongsideTransition: { _ in
            shadow.alpha = 1
        }) { _ in
            v.tintAdjustmentMode = .dimmed
        }
    }

    override func dismissalTransitionWillBegin() {
        let vc = self.presentingViewController
        let v = vc.view!
        let con = self.containerView!
        let shadow = con.subviews[0]
        let tc = vc.transitionCoordinator!
        tc.animate(alongsideTransition: { _ in
            shadow.alpha = 0
        }) { _ in
            v.tintAdjustmentMode = .automatic
        }
    }

    override var frameOfPresentedViewInContainerView : CGRect {
        // we want to center the presented view at its "native" size
        // I can think of a lot of ways to do this,
        // but here we just assume that it *is* its native size
        let v = self.presentedView!
        let con = self.containerView!
        v.center = CGPoint(x: con.bounds.midX, y: con.bounds.midY)
        return v.frame.integral
    }

    override func containerViewWillLayoutSubviews() {
        // deal with future rotation
        // again, I can think of more than one approach
        let v = self.presentedView!
        v.autoresizingMask = [
            .flexibleTopMargin, .flexibleBottomMargin,
            .flexibleLeftMargin, .flexibleRightMargin
        ]
        v.translatesAutoresizingMaskIntoConstraints = true
    }

}

extension CAVTransitioner { // UIViewControllerTransitioningDelegate
    func animationController(
        forPresented presented:UIViewController,
        presenting: UIViewController,
        source: UIViewController)
        -> UIViewControllerAnimatedTransitioning? {
            return self
    }

    func animationController(
        forDismissed dismissed: UIViewController)
        -> UIViewControllerAnimatedTransitioning? {
            return self
    }
}

extension CAVTransitioner : UIViewControllerAnimatedTransitioning {
    func transitionDuration(
        using transitionContext: UIViewControllerContextTransitioning?)
        -> TimeInterval {
            return 0.25
    }

    func animateTransition(
        using transitionContext: UIViewControllerContextTransitioning) {

        let con = transitionContext.containerView

        let v1 = transitionContext.view(forKey: .from)
        let v2 = transitionContext.view(forKey: .to)

        // we are using the same object (self) as animation controller
        // for both presentation and dismissal
        // so we have to distinguish the two cases

        if let v2 = v2 { // presenting
            con.addSubview(v2)
            let scale = CGAffineTransform(scaleX: 1.6, y: 1.6)
            v2.transform = scale
            v2.alpha = 0
            UIView.animate(withDuration: 0.25, animations: {
                v2.alpha = 1
                v2.transform = .identity
            }) { _ in
                transitionContext.completeTransition(true)
            }
        } else if let v1 = v1 { // dismissing
            UIView.animate(withDuration: 0.25, animations: {
                v1.alpha = 0
            }) { _ in
                transitionContext.completeTransition(true)
            }
        }

    }
}

Выглядит как много кода, и я полагаю, что так оно и есть, но он почти полностью ограничен одним классом, который является полностью стандартным; просто скопируйте и вставьте. Все, что вам нужно сделать, это написать внутренний интерфейс и поведение вашего "предупреждающего" контроллера представления, предоставляя ему кнопки и текст, и все, что вы хотите, так же, как вы делали бы это для любого другого контроллера представления.

Ответ 5

Вы можете использовать для его следующего фреймворка:

https://github.com/bananaRanger/SheetViewController

Это настраиваемый нативный контроллер уведомлений о листах.

Он имеет три типа действий: отдельно, внутренний, нет.

пример

Ответ 6

**## custom Alert UIView Class in swift 4**



import UIKit


    class Dialouge: UIView {
    @IBOutlet weak var lblTitle: UILabel!
    @IBOutlet weak var lblDescription: UILabel!
    @IBOutlet weak var btnLeft: UIButton!
    @IBOutlet weak var btnRight: UIButton!
    @IBOutlet weak var viewBg: UIButton!

    var leftAction  = {}
    var rightAction  = {}


    override func draw(_ rect: CGRect)
    {

        self.btnRight.layer.cornerRadius = self.btnRight.frame.height/2
        self.btnLeft.layer.cornerRadius = self.btnLeft.frame.height/2
        self.btnLeft.layer.borderWidth = 1.0
        self.btnLeft.layer.borderColor = #colorLiteral(red: 0.267678082, green: 0.2990377247, blue: 0.7881471515, alpha: 1)
    }
    @IBAction func leftAction(_ sender: Any) {

        leftAction()
    }

    @IBAction func rightAction(_ sender: Any) {
        rightAction()
    }
    @IBAction func bgTapped(_ sender: Any) {
        self.removeFromSuperview()
    }
    }

сильный текст
      ## Использование настраиваемого оповещения с помощью вкладки.

    let custView = Bundle.main.loadNibNamed("Dialouge", owner: self, options: 
     nil)![0] as? Dialouge
        custView?.lblDescription.text = "Are you sure you want to delete post?"
        custView?.lblTitle.text = "Delete Post"
        custView?.btnLeft.setTitle("Yes", for: .normal)
        custView?.btnRight.setTitle("No", for: .normal)
        custView?.leftAction = {
            self.deletePost(postId: self.curr_post.id,completion: {
                custView?.removeFromSuperview()
            })
        }
        custView?.rightAction = {
            custView?.removeFromSuperview()
        }
        if let tbc = self.parentt?.tabBarController {
            custView?.frame = tbc.view.frame
            DispatchQueue.main.async {
                tbc.view.addSubview(custView!)
            }
        }else if let tbc = self.parView?.parenttprof {
            custView?.frame = tbc.view.frame
            DispatchQueue.main.async {
                tbc.view.addSubview(custView!)
            }
        }
        else
        {
            custView?.frame = self.parView?.view.frame ?? CGRect.zero
            DispatchQueue.main.async {
                self.parView?.view.addSubview(custView!)
            }
            }