在iOS中显示与Android Toast具有相同功能的消息

Displaying a message in iOS which has the same functionality as Toast in Android

我需要知道iOS中是否有任何方法的行为类似于Android中的Toast消息。 也就是说,我需要显示一条消息,几秒钟后会自动将其关闭。 这类似于Android环境中Toast类的功能。


您可以使用MBProgressHUD项目。

将HUD模式MBProgressHUDModeText用于类似吐司的行为,

1
2
3
4
5
6
7
8
9
10
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];

// Configure for text only and offset down
hud.mode = MBProgressHUDModeText;
hud.label.text = @"Some message...";
hud.margin = 10.f;
hud.yOffset = 150.f;
hud.removeFromSuperViewOnHide = YES;

[hud hideAnimated:YES afterDelay:3];

enter image description here


1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSString *message = @"Some message...";

UIAlertView *toast = [[UIAlertView alloc] initWithTitle:nil
                                                message:message
                                               delegate:nil
                                      cancelButtonTitle:nil
                                      otherButtonTitles:nil, nil];
[toast show];

int duration = 1; // duration in seconds

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [toast dismissWithClickedButtonIndex:0 animated:YES];
});

使用iOS 9或更高版本的UIAlertViewController

1
2
3
4
5
6
7
8
9
10
11
12
13
NSString *message = @"Some message...";

UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                                               message:message
                                                        preferredStyle:UIAlertControllerStyleAlert];

[self presentViewController:alert animated:YES completion:nil];

int duration = 1; // duration in seconds

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
    [alert dismissViewControllerAnimated:YES completion:nil];
});

迅捷3.2

1
2
3
4
5
6
7
8
9
10
let message ="Some message..."
let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
self.present(alert, animated: true)

// duration in seconds
let duration: Double = 5

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + duration) {
    alert.dismiss(animated: true)
}


在Android中,Toast是一条短消息,它会在屏幕上显示一小段时间,然后自动消失,而不会干扰用户与该应用的交互。

enter image description here

因此,许多来自Android背景的人都想知道Toast的iOS版本是什么。除了当前问题,还可以在此处,此处和此处找到其他类似的问题。答案是在iOS中没有与Toast完全相同的东西。但是,已经提出了各种解决方法,包括

  • UIView制作自己的Toast(请参见此处,此处,此处和此处)
  • 导入模仿Toast的第三方项目(请参见此处,此处,此处和此处)
  • 使用带有计时器的无按钮警报(请参阅此处)

但是,我的建议是坚持使用iOS随附的标准UI选项。不要试图使您的应用外观和行为与Android版本完全相同。考虑如何重新包装它,使其外观和感觉像一个iOS应用程序。有关某些选择,请参见以下链接。

  • 用于临时向用户显示信息的标准iOS选项概述。

考虑以传达相同信息的方式重新设计UI。或者,如果信息非常重要,那么警报可能是答案。


斯威夫特4

这个小把戏怎么样?

1
2
3
4
5
6
7
8
9
10
11
12
func showToast(controller: UIViewController, message : String, seconds: Double) {
    let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
    alert.view.backgroundColor = UIColor.black
    alert.view.alpha = 0.6
    alert.view.layer.cornerRadius = 15

    controller.present(alert, animated: true)

    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds) {
        alert.dismiss(animated: true)
    }
}

调用示例:

1
showToast(controller: self, message :"This is a test", seconds: 2.0)


迅捷3

对于没有第三方代码的简单解决方案:

enter image description here

只需使用普通的UIAlertController,但使用style = actionSheet(请看下面的代码)

1
2
3
4
5
6
let alertDisapperTimeInSeconds = 2.0
let alert = UIAlertController(title: nil, message:"Toast!", preferredStyle: .actionSheet)
self.present(alert, animated: true)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + alertDisapperTimeInSeconds) {
  alert.dismiss(animated: true)
}

该解决方案的优势:

  • 像Toast消息一样的Android
  • 仍然是iOS外观

  • 对于Swift 3和4:

    使用烤面包机库

    1
    Toast(text:"Hello, world!", duration: Delay.long)

    enter image description here

    对于Swift 2:

    使用JLToast


    Swift 4.0:

    制作一个新的swift文件。 (文件新文件空的Swift文件)。将其命名为UIViewToast。添加以下代码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    import UIKit

    func /(lhs: CGFloat, rhs: Int) -> CGFloat {
    return lhs / CGFloat(rhs)
    }

    let HRToastDefaultDuration  =   2.0
    let HRToastFadeDuration     =   0.2
    let HRToastHorizontalMargin : CGFloat  =   10.0
    let HRToastVerticalMargin   : CGFloat  =   10.0

    let HRToastPositionDefault  =  "bottom"
    let HRToastPositionTop      =  "top"
    let HRToastPositionCenter   =  "center"

    // activity
    let HRToastActivityWidth  :  CGFloat  = 100.0
    let HRToastActivityHeight :  CGFloat  = 100.0
    let HRToastActivityPositionDefault    ="center"

    // image size
    let HRToastImageViewWidth :  CGFloat  = 80.0
    let HRToastImageViewHeight:  CGFloat  = 80.0

    // label setting
    let HRToastMaxWidth       :  CGFloat  = 0.8;      // 80% of parent view width
    let HRToastMaxHeight      :  CGFloat  = 0.8;
    let HRToastFontSize       :  CGFloat  = 16.0
    let HRToastMaxTitleLines              = 0
    let HRToastMaxMessageLines            = 0

    // shadow appearance
    let HRToastShadowOpacity  : CGFloat   = 0.8
    let HRToastShadowRadius   : CGFloat   = 6.0
    let HRToastShadowOffset   : CGSize    = CGSize(width: 4.0, height: 4.0)

    let HRToastOpacity        : CGFloat   = 0.5
    let HRToastCornerRadius   : CGFloat   = 10.0

    var HRToastActivityView: UnsafePointer<UIView>?
    var HRToastTimer: UnsafePointer<Timer>?
    var HRToastView: UnsafePointer<UIView>?


    // Color Scheme
    let HRAppColor:UIColor = UIColor.black//UIappViewController().appUIColor
    let HRAppColor_2:UIColor = UIColor.white


    let HRToastHidesOnTap       =   true
    let HRToastDisplayShadow    =   false

    //HRToast (UIView + Toast using Swift)

    extension UIView {

    //public methods
    func makeToast(message msg: String) {
        self.makeToast(message: msg, duration: HRToastDefaultDuration, position: HRToastPositionDefault as AnyObject)
    }

    func makeToast(message msg: String, duration: Double, position: AnyObject) {
        let toast = self.viewForMessage(msg: msg, title: nil, image: nil)
        self.showToast(toast: toast!, duration: duration, position: position)
    }

    func makeToast(message msg: String, duration: Double, position: AnyObject, title: String) {
        let toast = self.viewForMessage(msg: msg, title: title, image: nil)
        self.showToast(toast: toast!, duration: duration, position: position)
    }

    func makeToast(message msg: String, duration: Double, position: AnyObject, image: UIImage) {
        let toast = self.viewForMessage(msg: msg, title: nil, image: image)
        self.showToast(toast: toast!, duration: duration, position: position)
    }

    func makeToast(message msg: String, duration: Double, position: AnyObject, title: String, image: UIImage) {
        let toast = self.viewForMessage(msg: msg, title: title, image: image)
        self.showToast(toast: toast!, duration: duration, position: position)
    }

    func showToast(toast: UIView) {
        self.showToast(toast: toast, duration: HRToastDefaultDuration, position: HRToastPositionDefault as AnyObject)
    }

    func showToast(toast: UIView, duration: Double, position: AnyObject) {
        let existToast = objc_getAssociatedObject(self, &HRToastView) as! UIView?
        if existToast != nil {
            if let timer: Timer = objc_getAssociatedObject(existToast!, &HRToastTimer) as? Timer {
                timer.invalidate();
            }
            self.hideToast(toast: existToast!, force: false);
        }

        toast.center = self.centerPointForPosition(position: position, toast: toast)
        toast.alpha = 0.0

        if HRToastHidesOnTap {
            let tapRecognizer = UITapGestureRecognizer(target: toast, action: #selector(handleToastTapped(recognizer:)))
            toast.addGestureRecognizer(tapRecognizer)
            toast.isUserInteractionEnabled = true;
            toast.isExclusiveTouch = true;
        }

        self.addSubview(toast)
        objc_setAssociatedObject(self, &HRToastView, toast, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)

        UIView.animate(withDuration: HRToastFadeDuration,
                                   delay: 0.0, options: ([.curveEaseOut, .allowUserInteraction]),
                                   animations: {
                                    toast.alpha = 1.0
        },
                                   completion: { (finished: Bool) in
                                    let timer = Timer.scheduledTimer(timeInterval: duration, target: self, selector: #selector(self.toastTimerDidFinish(timer:)), userInfo: toast, repeats: false)
                                    objc_setAssociatedObject(toast, &HRToastTimer, timer, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        })
    }

    func makeToastActivity() {
        self.makeToastActivity(position: HRToastActivityPositionDefault as AnyObject)
    }

    func showToastActivity() {
        self.isUserInteractionEnabled = false
        self.makeToastActivity()
    }

    func removeToastActivity() {
        self.isUserInteractionEnabled = true
        self.hideToastActivity()

    }

    func makeToastActivityWithMessage(message msg: String){
        self.makeToastActivity(position: HRToastActivityPositionDefault as AnyObject, message: msg)
    }
    func makeToastActivityWithMessage(message msg: String,addOverlay: Bool){

        self.makeToastActivity(position: HRToastActivityPositionDefault as AnyObject, message: msg,addOverlay: true)
    }

    func makeToastActivity(position pos: AnyObject, message msg: String ="",addOverlay overlay: Bool = false) {
        let existingActivityView: UIView? = objc_getAssociatedObject(self, &HRToastActivityView) as? UIView
        if existingActivityView != nil { return }

        let activityView = UIView(frame: CGRect(x:0, y:0, width: self.frame.width, height: self.frame.height))
        activityView.center = self.centerPointForPosition(position: pos, toast: activityView)
        activityView.alpha = 0.0
        activityView.autoresizingMask = ([.flexibleLeftMargin, .flexibleTopMargin, .flexibleRightMargin, .flexibleBottomMargin])
        activityView.layer.cornerRadius = HRToastCornerRadius

        if HRToastDisplayShadow {
            activityView.layer.shadowColor = UIColor.black.cgColor
            activityView.layer.shadowOpacity = Float(HRToastShadowOpacity)
            activityView.layer.shadowRadius = HRToastShadowRadius
            activityView.layer.shadowOffset = HRToastShadowOffset
        }

        let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)
        activityIndicatorView.center = CGPoint(x:activityView.bounds.size.width / 2, y: activityView.bounds.size.height / 2)
        activityIndicatorView.color = HRAppColor
        activityView.addSubview(activityIndicatorView)
        activityIndicatorView.startAnimating()

        if (!msg.isEmpty){
            activityIndicatorView.frame.origin.y -= 10



            let activityMessageLabel = UILabel(frame: CGRect(x: activityView.bounds.origin.x, y: (activityIndicatorView.frame.origin.y + activityIndicatorView.frame.size.height + 10), width: activityView.bounds.size.width, height: 20))
            activityMessageLabel.textColor = UIColor.white
            activityMessageLabel.font = (msg.count<=10) ? UIFont(name:activityMessageLabel.font.fontName, size: 16) : UIFont(name:activityMessageLabel.font.fontName, size: 16)
            activityMessageLabel.textAlignment = .center
            activityMessageLabel.text = msg +".."
            if overlay {
                activityMessageLabel.textColor = UIColor.white
                activityView.backgroundColor = HRAppColor.withAlphaComponent(HRToastOpacity)
                activityIndicatorView.color = UIColor.white
            }
            else {
                activityMessageLabel.textColor = HRAppColor
                activityView.backgroundColor = UIColor.clear
                activityIndicatorView.color = HRAppColor
            }

            activityView.addSubview(activityMessageLabel)

        }

        self.addSubview(activityView)

        // associate activity view with self
        objc_setAssociatedObject(self, &HRToastActivityView, activityView, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)

        UIView.animate(withDuration: HRToastFadeDuration,
                                   delay: 0.0,
                                   options: UIViewAnimationOptions.curveEaseOut,
                                   animations: {
                                    activityView.alpha = 1.0
        },
                                   completion: nil)
        self.isUserInteractionEnabled = false
    }

    func hideToastActivity() {
        self.isUserInteractionEnabled = true
        let existingActivityView = objc_getAssociatedObject(self, &HRToastActivityView) as! UIView?
        if existingActivityView == nil { return }
        UIView.animate(withDuration: HRToastFadeDuration,
                                   delay: 0.0,
                                   options: UIViewAnimationOptions.curveEaseOut,
                                   animations: {
                                    existingActivityView!.alpha = 0.0
        },
                                   completion: { (finished: Bool) in
                                    existingActivityView!.removeFromSuperview()
                                    objc_setAssociatedObject(self, &HRToastActivityView, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        })
    }

    /*
     *  private methods (helper)
     */
    func hideToast(toast: UIView) {
        self.isUserInteractionEnabled = true
        self.hideToast(toast: toast, force: false);
    }

    func hideToast(toast: UIView, force: Bool) {
        let completeClosure = { (finish: Bool) -> () in
            toast.removeFromSuperview()
            objc_setAssociatedObject(self, &HRToastTimer, nil, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }

        if force {
            completeClosure(true)
        } else {
            UIView.animate(withDuration: HRToastFadeDuration,
                                       delay: 0.0,
                                       options: ([.curveEaseIn, .beginFromCurrentState]),
                                       animations: {
                                        toast.alpha = 0.0
            },
                                       completion:completeClosure)
        }
    }

    @objc func toastTimerDidFinish(timer: Timer) {
        self.hideToast(toast: timer.userInfo as! UIView)
    }

    @objc func handleToastTapped(recognizer: UITapGestureRecognizer) {

        // var timer = objc_getAssociatedObject(self, &HRToastTimer) as! NSTimer
        // timer.invalidate()

        self.hideToast(toast: recognizer.view!)
    }

    func centerPointForPosition(position: AnyObject, toast: UIView) -> CGPoint {
        if position is String {
            let toastSize = toast.bounds.size
            let viewSize  = self.bounds.size
            if position.lowercased == HRToastPositionTop {
                return CGPoint(x: viewSize.width/2, y: toastSize.height/2 + HRToastVerticalMargin)

            } else if position.lowercased == HRToastPositionDefault {
                return CGPoint(x:viewSize.width/2, y:viewSize.height - toastSize.height - 15 - HRToastVerticalMargin)
            } else if position.lowercased == HRToastPositionCenter {
                return CGPoint(x:viewSize.width/2, y:viewSize.height/2)
            }
        } else if position is NSValue {
            return position.cgPointValue
        }

        print("Warning: Invalid position for toast.")
        return self.centerPointForPosition(position: HRToastPositionDefault as AnyObject, toast: toast)
    }

    func viewForMessage(msg: String?, title: String?, image: UIImage?) -> UIView? {
        if msg == nil && title == nil && image == nil { return nil }

        var msgLabel: UILabel?
        var titleLabel: UILabel?
        var imageView: UIImageView?

        let wrapperView = UIView()
        wrapperView.autoresizingMask = ([.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin])
        wrapperView.layer.cornerRadius = HRToastCornerRadius
        wrapperView.backgroundColor = UIColor.black.withAlphaComponent(HRToastOpacity)

        if HRToastDisplayShadow {
            wrapperView.layer.shadowColor = UIColor.black.cgColor
            wrapperView.layer.shadowOpacity = Float(HRToastShadowOpacity)
            wrapperView.layer.shadowRadius = HRToastShadowRadius
            wrapperView.layer.shadowOffset = HRToastShadowOffset
        }

        if image != nil {
            imageView = UIImageView(image: image)
            imageView!.contentMode = .scaleAspectFit
            imageView!.frame = CGRect(x:HRToastHorizontalMargin, y: HRToastVerticalMargin, width: CGFloat(HRToastImageViewWidth), height: CGFloat(HRToastImageViewHeight))
        }

        var imageWidth: CGFloat, imageHeight: CGFloat, imageLeft: CGFloat
        if imageView != nil {
            imageWidth = imageView!.bounds.size.width
            imageHeight = imageView!.bounds.size.height
            imageLeft = HRToastHorizontalMargin
        } else {
            imageWidth  = 0.0; imageHeight = 0.0; imageLeft   = 0.0
        }

        if title != nil {
            titleLabel = UILabel()
            titleLabel!.numberOfLines = HRToastMaxTitleLines
            titleLabel!.font = UIFont.boldSystemFont(ofSize: HRToastFontSize)
            titleLabel!.textAlignment = .center
            titleLabel!.lineBreakMode = .byWordWrapping
            titleLabel!.textColor = UIColor.white
            titleLabel!.backgroundColor = UIColor.clear
            titleLabel!.alpha = 1.0
            titleLabel!.text = title

            // size the title label according to the length of the text

            let maxSizeTitle = CGSize(width: (self.bounds.size.width * HRToastMaxWidth) - imageWidth, height: self.bounds.size.height * HRToastMaxHeight)

            let expectedHeight = title!.stringHeightWithFontSize(fontSize: HRToastFontSize, width: maxSizeTitle.width)
            titleLabel!.frame = CGRect(x: 0.0, y: 0.0, width: maxSizeTitle.width, height: expectedHeight)
        }

        if msg != nil {
            msgLabel = UILabel();
            msgLabel!.numberOfLines = HRToastMaxMessageLines
            msgLabel!.font = UIFont.systemFont(ofSize: HRToastFontSize)
            msgLabel!.lineBreakMode = .byWordWrapping
            msgLabel!.textAlignment = .center
            msgLabel!.textColor = UIColor.white
            msgLabel!.backgroundColor = UIColor.clear
            msgLabel!.alpha = 1.0
            msgLabel!.text = msg


            let maxSizeMessage = CGSize(width: (self.bounds.size.width * HRToastMaxWidth) - imageWidth, height: self.bounds.size.height * HRToastMaxHeight)
            let expectedHeight = msg!.stringHeightWithFontSize(fontSize: HRToastFontSize, width: maxSizeMessage.width)
            msgLabel!.frame = CGRect(x: 0.0, y: 0.0, width: maxSizeMessage.width, height: expectedHeight)
        }

        var titleWidth: CGFloat, titleHeight: CGFloat, titleTop: CGFloat, titleLeft: CGFloat
        if titleLabel != nil {
            titleWidth = titleLabel!.bounds.size.width
            titleHeight = titleLabel!.bounds.size.height
            titleTop = HRToastVerticalMargin
            titleLeft = imageLeft + imageWidth + HRToastHorizontalMargin
        } else {
            titleWidth = 0.0; titleHeight = 0.0; titleTop = 0.0; titleLeft = 0.0
        }

        var msgWidth: CGFloat, msgHeight: CGFloat, msgTop: CGFloat, msgLeft: CGFloat
        if msgLabel != nil {
            msgWidth = msgLabel!.bounds.size.width
            msgHeight = msgLabel!.bounds.size.height
            msgTop = titleTop + titleHeight + HRToastVerticalMargin
            msgLeft = imageLeft + imageWidth + HRToastHorizontalMargin
        } else {
            msgWidth = 0.0; msgHeight = 0.0; msgTop = 0.0; msgLeft = 0.0
        }

        let largerWidth = max(titleWidth, msgWidth)
        let largerLeft  = max(titleLeft, msgLeft)

        // set wrapper view's frame
        let wrapperWidth  = max(imageWidth + HRToastHorizontalMargin * 2, largerLeft + largerWidth + HRToastHorizontalMargin)
        let wrapperHeight = max(msgTop + msgHeight + HRToastVerticalMargin, imageHeight + HRToastVerticalMargin * 2)
        wrapperView.frame = CGRect(x: 0.0, y: 0.0, width: wrapperWidth, height: wrapperHeight)

        // add subviews
        if titleLabel != nil {
            titleLabel!.frame = CGRect(x: titleLeft, y: titleTop, width: titleWidth, height: titleHeight)
            wrapperView.addSubview(titleLabel!)
        }
        if msgLabel != nil {
            msgLabel!.frame = CGRect(x: msgLeft, y: msgTop, width: msgWidth, height: msgHeight)
            wrapperView.addSubview(msgLabel!)
        }
        if imageView != nil {
            wrapperView.addSubview(imageView!)
        }

        return wrapperView
        }

        }

    extension String {

    func stringHeightWithFontSize(fontSize: CGFloat,width: CGFloat) -> CGFloat {
        let font = UIFont.systemFont(ofSize: fontSize)
        let size = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineBreakMode = .byWordWrapping;
        let attributes = [NSAttributedStringKey.font:font,
                          NSAttributedStringKey.paragraphStyle:paragraphStyle.copy()]

        let text = self as NSString
        let rect = text.boundingRect(with: size, options:.usesLineFragmentOrigin, attributes: attributes, context:nil)
        return rect.size.height
    }
    }

    用法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
      self.view.makeToast(message:"Simple Toast")
      self.view.makeToast(message:"Simple Toast", duration: 2.0, position:HRToastPositionTop)

      self.view.makeToast(message:"Simple Toast", duration: 2.0, position: HRToastPositionCenter, image: UIImage(named:"ic_120x120")!)

      self.view.makeToast(message:"It is just awesome", duration: 2.0, position: HRToastPositionDefault, title:"Simple Toast")

      self.view.makeToast(message:"It is just awesome", duration: 2.0, position: HRToastPositionCenter, title:"Simple Toast", image: UIImage(named:"ic_120x120")!)

      self.view.makeToastActivity()
      self.view.makeToastActivity(position: HRToastPositionCenter)
      self.view.makeToastActivity(position: HRToastPositionDefault, message:"Loading")
      self.view.makeToastActivityWithMessage(message:"Loading")

      // Hide Toast
      self.view.hideToast(toast: self.view)
      self.view.hideToast(toast: self.view, force: true)
      self.view.hideToastActivity()


    如果您想使用iOS风格,请从Github下载此框架

    iOS Toast警报查看框架

    导入框架后,此示例将在您的UIViewController上运行。

    范例1:

    1
    2
    3
    4
    5
    6
    //Manual
    let tav = ToastAlertView()
    tav.message ="Hey!"
    tav.image = UIImage(named:"img1")!
    tav.show()
    //tav.dismiss() to Hide

    范例2:

    1
    2
    3
    4
    5
    6
    //Toast Alert View with Time Dissmis Only
    self.showToastAlert("5 Seconds",
                    image: UIImage(named:"img1")!,
                    hideWithTap: false,
                    hideWithTime: true,
                    hideTime: 5.0)

    最后:

    Toast Alert View Image Example


    对于使用Xamarin.IOS的用户,您可以这样做:

    1
    new UIAlertView(null, message, null,"OK", null).Show();

    使用UIKit;是必须的。


    使用Alert的Android Toast的Swift实现,该警告会在3秒钟后消失。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        func showAlertView(title: String?, message: String?) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        let okAction = UIAlertAction(title:"OK", style: .Cancel, handler: nil)
        alertController.addAction(okAction)
        self.presentViewController(alertController, animated: true, completion: nil)


        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3 * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue()) {
            print("Bye. Lovvy")
            alertController.dismissViewControllerAnimated(true, completion: nil)
        }
    }

    简单地说:

    1
    self.showAlertView("Message sent...", message: nil)

    Swift 4语法延迟3秒:

    1
    2
    3
    4
    5
    present(alertController, animated: true, completion: nil)

    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {                
        self.dismiss(animated: true, completion: nil)    
    }


    对我来说,这个解决方案很好:
    https://github.com/cruffenach/CRToast

    enter image description here

    示例如何使用它:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        NSDictionary *options = @{
                              kCRToastTextKey : @"Hello World!",
                              kCRToastTextAlignmentKey : @(NSTextAlignmentCenter),
                              kCRToastBackgroundColorKey : [UIColor redColor],
                              kCRToastAnimationInTypeKey : @(CRToastAnimationTypeGravity),
                              kCRToastAnimationOutTypeKey : @(CRToastAnimationTypeGravity),
                              kCRToastAnimationInDirectionKey : @(CRToastAnimationDirectionLeft),
                              kCRToastAnimationOutDirectionKey : @(CRToastAnimationDirectionRight)
                              };
    [CRToastManager showNotificationWithOptions:options
                                completionBlock:^{
                                    NSLog(@"Completed");
                                }];

    这是您的解决方案:
    将下面的代码放入您的Xcode项目中并享受,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    - (void)showMessage:(NSString*)message atPoint:(CGPoint)point {
    const CGFloat fontSize = 16;

    UILabel* label = [[UILabel alloc] initWithFrame:CGRectZero];
    label.backgroundColor = [UIColor clearColor];
    label.font = [UIFont fontWithName:@"Helvetica-Bold" size:fontSize];
    label.text = message;
    label.textColor = UIColorFromRGB(0x07575B);
    [label sizeToFit];

    label.center = point;

    [self.view addSubview:label];

    [UIView animateWithDuration:0.3 delay:1 options:0 animations:^{
        label.alpha = 0;
    } completion:^(BOOL finished) {
        label.hidden = YES;
        [label removeFromSuperview];
    }];
    }

    如何使用 ?

    1
    [self showMessage:@"Toast in iOS" atPoint:CGPointMake(160, 695)];

    同样,如果在Xamarin上使用IOS,则在组件存储中有一个名为BTProgressHUD的新组件


    1)从此链接下载toast-notifications-ios

    2)转到目标->构建阶段,并将-fno-objc-arc添加到相关文件的"编译器源"中

    3)制作函数并#import"iToast.h"

    1
    2
    3
    4
    5
    6
    7
    -(void)showToast :(NSString *)strMessage {
        iToast * objiTost = [iToast makeText:strMessage];
        [objiTost setFontSize:11];
        [objiTost setDuration:iToastDurationNormal];
        [objiTost setGravity:iToastGravityBottom];
        [objiTost show];
    }

    4)在需要显示吐司消息的地方打电话

    1
    [self showToast:@"This is example text."];

    我想了一个简单的方法做烤面包!使用不带按钮的UIAlertController!我们使用按钮文字作为我们的信息!得到它?
    参见下面的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    func alert(title: String?, message: String?, bdy:String) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        let okAction = UIAlertAction(title: bdy, style: .Cancel, handler: nil)
        alertController.addAction(okAction)
            self.presentViewController(alertController, animated: true, completion: nil)


        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2 * Double(NSEC_PER_SEC)))
        dispatch_after(delayTime, dispatch_get_main_queue()) {
            //print("Bye. Lovvy")
            alertController.dismissViewControllerAnimated(true, completion: nil)
        }    
    }

    像这样使用它:

    1
    2
    self.alert(nil,message:nil,bdy:"Simple Toast!") // toast
    self.alert(nil,message:nil,bdy:"Alert") // alert with"Alert" button


    这就是我在Swift 3.0中所做的事情。我创建了UIView扩展,并调用了self.view.showToast(message:" Message Here",持续时间:3.0)和self.view.hideToast()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    extension UIView{
    var showToastTag :Int {return 999}

    //Generic Show toast
    func showToast(message : String, duration:TimeInterval) {

        let toastLabel = UILabel(frame: CGRect(x:0, y:0, width: (self.frame.size.width)-60, height:64))

        toastLabel.backgroundColor = UIColor.gray
        toastLabel.textColor = UIColor.black
        toastLabel.numberOfLines = 0
        toastLabel.layer.borderColor = UIColor.lightGray.cgColor
        toastLabel.layer.borderWidth = 1.0
        toastLabel.textAlignment = .center;
        toastLabel.font = UIFont(name:"HelveticaNeue", size: 17.0)
        toastLabel.text = message
        toastLabel.center = self.center
        toastLabel.isEnabled = true
        toastLabel.alpha = 0.99
        toastLabel.tag = showToastTag
        toastLabel.layer.cornerRadius = 10;
        toastLabel.clipsToBounds  =  true
        self.addSubview(toastLabel)

        UIView.animate(withDuration: duration, delay: 0.1, options: .curveEaseOut, animations: {
            toastLabel.alpha = 0.95
        }, completion: {(isCompleted) in
            toastLabel.removeFromSuperview()
        })
    }

    //Generic Hide toast
    func hideToast(){
        if let view = self.viewWithTag(self.showToastTag){
            view.removeFromSuperview()
        }
      }
    }

    如果您想要纯粹的快捷方式,我们发布了内部文件。很简单

    https://github.com/gglresearchanddevelopment/ios-toast


    对于Swift 2.0并考虑https://stackoverflow.com/a/5079536/6144027

    1
    2
    3
    4
    5
    6
    7
                    //TOAST
                    let alertController = UIAlertController(title:"", message:"This is a Toast.LENGTH_SHORT", preferredStyle: .Alert)
                    self!.presentViewController(alertController, animated: true, completion: nil)
                    let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC)))
                    dispatch_after(delayTime, dispatch_get_main_queue()) {
                        alertController.dismissViewControllerAnimated(true, completion: nil)
                    }