【问题标题】:What is the android.widget.Toast equivalent for iOS applications?iOS 应用程序的 android.widget.Toast 等效项是什么?
【发布时间】:2011-04-01 04:10:24
【问题描述】:

几个月前我制作了 Android 应用程序。 Toast 课程对我非常有用。 我不需要考虑主线程和显示它的位置。我可以在任何地方显示它,然后离开它,它就会自动消失。

Toast.makeToast(context, msg, Toast.LENGTH_SHORT).show();

就是这样。 ^^

iPhone 呢?有没有像吐司这样的东西?只显示消息,不需要关心它。它会自动消失。

【问题讨论】:

  • 考虑到只有 iOS 4 允许后台应用程序,以前不需要这样的功能。毫无疑问有人会做一个,但我不熟悉类似的东西。
  • @StephenFurlani,虽然不是很明显,但 toast 消息在前台应用程序中也很有用,并且被广泛使用。
  • @DanielS。我完全同意。但是,OP 已经快 4 岁了。在这一点上,iOS 8 有一些关于 UIPopoverPresentationControllers 和 passthroughViews 的出色功能

标签: ios toast


【解决方案1】:

我已经为 Android 编写了很长时间,但我想念 Toast。我已经实现了一个。需要代码吗?你在这里:

ToastView.h

#import <UIKit/UIKit.h>

@interface ToastView : UIView

@property (strong, nonatomic) NSString *text;

+ (void)showToastInParentView: (UIView *)parentView withText:(NSString *)text withDuaration:(float)duration;

@end

ToastView.m

#import "ToastView.h"

@interface ToastView ()
@property (strong, nonatomic, readonly) UILabel *textLabel;
@end
@implementation ToastView
@synthesize textLabel = _textLabel;

float const ToastHeight = 50.0f;
float const ToastGap = 10.0f;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

-(UILabel *)textLabel
{
    if (!_textLabel) {
        _textLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 5.0, self.frame.size.width - 10.0, self.frame.size.height - 10.0)];
        _textLabel.backgroundColor = [UIColor clearColor];
        _textLabel.textAlignment = NSTextAlignmentCenter;
        _textLabel.textColor = [UIColor whiteColor];
        _textLabel.numberOfLines = 2;
        _textLabel.font = [UIFont systemFontOfSize:13.0];
        _textLabel.lineBreakMode = NSLineBreakByCharWrapping;
        [self addSubview:_textLabel];

    }
    return _textLabel;
}

- (void)setText:(NSString *)text
{
    _text = text;
    self.textLabel.text = text;
}

+ (void)showToastInParentView: (UIView *)parentView withText:(NSString *)text withDuaration:(float)duration;
{

    //Count toast views are already showing on parent. Made to show several toasts one above another
    int toastsAlreadyInParent = 0;
    for (UIView *subView in [parentView subviews]) {
        if ([subView isKindOfClass:[ToastView class]])
        {
            toastsAlreadyInParent++;
        }
    }

    CGRect parentFrame = parentView.frame;

    float yOrigin = parentFrame.size.height - (70.0 + ToastHeight * toastsAlreadyInParent + ToastGap * toastsAlreadyInParent);

    CGRect selfFrame = CGRectMake(parentFrame.origin.x + 20.0, yOrigin, parentFrame.size.width - 40.0, ToastHeight);
    ToastView *toast = [[ToastView alloc] initWithFrame:selfFrame];

    toast.backgroundColor = [UIColor darkGrayColor];
    toast.alpha = 0.0f;
    toast.layer.cornerRadius = 4.0;
    toast.text = text;

    [parentView addSubview:toast];

    [UIView animateWithDuration:0.4 animations:^{
        toast.alpha = 0.9f;
        toast.textLabel.alpha = 0.9f;
    }completion:^(BOOL finished) {
        if(finished){

        }
    }];


    [toast performSelector:@selector(hideSelf) withObject:nil afterDelay:duration];

}

- (void)hideSelf
{

    [UIView animateWithDuration:0.4 animations:^{
        self.alpha = 0.0;
        self.textLabel.alpha = 0.0;
    }completion:^(BOOL finished) {
        if(finished){
            [self removeFromSuperview];
        }
    }];
}

@end

从 ViewController 调用

 [ToastView showToastInParentView:self.view withText:@"What a toast!" withDuaration:5.0];

【讨论】:

  • 太好了(@Scarmysun:除了实现主体之前的额外冒号。所以不会让我做那么短的编辑,否则我会修复它..)。赞成
  • 这对我来说崩溃了,直到我将“setTextLabel:”重命名为别的东西。 “setTextLabel:”在属性更新时自动调用(因为属性只是使用 getter 或 setter 的简写)。在我进行更改后,它运行良好。
  • 很好的评论@BeccaP。我已经更新了我的实现。现在文本标签是私有财产并且被懒惰地实例化。添加了“文本”公共属性。
  • 我不得不改变 int toastsAlreadyInParent = 0;到 1 否则我必须调用它两次才能显示。
  • 这是一个不错的小物件。做得好。请注意,在设置ToastView 框架时,您需要使用父视图的bounds,而不是frame。所以这一行:CGRect parentFrame = parentView.frame; 应该是CGRect parentFrame = parentView.bounds;。除非您的父视图具有非零帧原点,否则您不会看到此错误。
【解决方案2】:

UIKit 中没有“开箱即用”的类来执行此操作。但是创建一个提供这种行为的类是很容易的。

你只需要创建一个继承自 UIView 的类。这个班级将有责任 - 创建您想要显示的内容, - 将自身添加到父视图层次结构中 - 使用计时器关闭自己。

你可以像这样使用它:

[ToastView toastViewInView:myParentView withText:@"what a wonderful text"];

问候, 昆汀

【讨论】:

  • 没有代码示例?您只建议了一个用于 toast 的 API。
  • 我有一个更好的解决方案,只需编写如下代码: import ProjectGenerator wonder.insertFinishedProject() ...它应该可以工作。
  • 您可以在此线程中找到下面的代码示例。谢谢@Scarmysun
  • @Josh,除非你多次调用 DoWhatIMean 过程,否则这并不好。
【解决方案3】:

【讨论】:

    【解决方案4】:

    您可以通过多种方式做到这一点,其中一种方法是在swift3 中使用UIAlertViewController()

    let alertManager=UIAlertController(title: nil, message: "Welcome!", preferredStyle: .alert)
    
    self.present(alertManager, animated: true, completion: nil)
    
    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1,
     execute: {
                                        alertManager.dismiss(animated: false, completion: nil)
    
                                    })
    

    【讨论】:

      【解决方案5】:

      编辑:针对 Swift 3 更新

      这是基于 wojciech_maciejewski 回答的 Swift 3 版本。这看起来更像 Android Toast 并且不会相互堆叠 toast。它将吐司吸引到屏幕的中心。它可以处理长的多行文本。

      import UIKit
      
      class ToastView: UIView {
      
          private static let hLabelGap: CGFloat = 40.0
          private static let vLabelGap: CGFloat = 20.0
          private static let hToastGap: CGFloat = 20.0
          private static let vToastGap: CGFloat = 10.0
      
          private var textLabel: UILabel!
      
          static func showInParent(_ parentView: UIView, _ text: String, duration: Double = 3.0) {
              let labelFrame = CGRect(x: parentView.frame.origin.x + hLabelGap,
                                      y: parentView.frame.origin.y + vLabelGap,
                                      width: parentView.frame.width - 2 * hLabelGap,
                                      height: parentView.frame.height - 2 * vLabelGap)
              let label = UILabel()
              label.font = UIFont.systemFont(ofSize: 15.0)
              label.text = text
              label.backgroundColor = UIColor.clear
              label.textAlignment = NSTextAlignment.center
              label.textColor = UIColor.white
              label.numberOfLines = 0
              label.frame = labelFrame
              label.sizeToFit()
      
              let toast = ToastView()
              toast.textLabel = label
              toast.addSubview(label)
              toast.frame = CGRect(x: label.frame.origin.x - hToastGap,
                                   y: label.frame.origin.y - vToastGap,
                                   width: label.frame.width + 2 * hToastGap,
                                   height: label.frame.height + 2 * vToastGap)
              toast.backgroundColor = UIColor.darkGray
              toast.alpha = 0.0
              toast.layer.cornerRadius = 20.0
              toast.center = parentView.center
              label.center = CGPoint(x: toast.frame.size.width / 2, y: toast.frame.size.height / 2)
      
              parentView.addSubview(toast)
      
              UIView.animate(withDuration: 0.4, animations: {
                  toast.alpha = 0.9
                  label.alpha = 0.9
              })
      
              toast.perform(#selector(hideSelf), with: nil, afterDelay: duration)
          }
      
          @objc private func hideSelf() {
              UIView.animate(withDuration: 0.4, animations: {
                  self.alpha = 0.0
                  self.textLabel.alpha = 0.0
                  }, completion: { t in self.removeFromSuperview() })
          }
      }
      

      从另一个控制器使用:

      ToastView.showInParent(navigationController!.view, "Hello world")
      

      【讨论】:

        【解决方案6】:

        我正在发布 Scarmysun 的快速版本答案:)非常感谢

        import Foundation
        import UIKit
        
        class ToastView: UIView {
            static let toastHeight:CGFloat = 50.0
            static let toastGap:CGFloat = 10;
            lazy var textLabel: UILabel = UILabel(frame: CGRectMake(5.0, 5.0, self.frame.size.width - 10.0, self.frame.size.height - 10.0))
        
        
            static func showInParent(parentView: UIView!, withText text: String, forDuration duration: double_t) {
        
                //Count toast views are already showing on parent. Made to show several toasts one above another
                var toastsAlreadyInParent = 0;
        
                for view in parentView.subviews {
                    if (view.isKindOfClass(ToastView)) {
                        toastsAlreadyInParent++
                    }
                }
        
                var parentFrame = parentView.frame;
        
                var yOrigin = parentFrame.size.height - getDouble(toastsAlreadyInParent)
        
                var selfFrame = CGRectMake(parentFrame.origin.x + 20.0, yOrigin, parentFrame.size.width - 40.0, toastHeight);
                var toast = ToastView(frame: selfFrame)
        
                toast.textLabel.backgroundColor = UIColor.clearColor()
                toast.textLabel.textAlignment = NSTextAlignment.Center
                toast.textLabel.textColor = UIColor.whiteColor()
                toast.textLabel.numberOfLines = 2
                toast.textLabel.font = UIFont.systemFontOfSize(13.0)
                toast.addSubview(toast.textLabel)
        
                toast.backgroundColor = UIColor.darkGrayColor()
                toast.alpha = 0.0;
                toast.layer.cornerRadius = 4.0;
                toast.textLabel.text = text;
        
                parentView.addSubview(toast)
                UIView.animateWithDuration(0.4, animations: {
                    toast.alpha = 0.9
                    toast.textLabel.alpha = 0.9
                })
        
        
                toast.performSelector(Selector("hideSelf"), withObject: nil, afterDelay: duration)
        
            }
        
            static private func getDouble(toastsAlreadyInParent : Int) -> CGFloat {
                return (70.0 + toastHeight * CGFloat(toastsAlreadyInParent) + toastGap * CGFloat(toastsAlreadyInParent));
            }
        
             func hideSelf() {
                UIView.animateWithDuration(0.4, animations: {
                    self.alpha = 0.0
                    self.textLabel.alpha = 0.0
                }, completion: { t in self.removeFromSuperview() })
            }
        
        }
        

        【讨论】:

          猜你喜欢
          • 2020-07-25
          • 1970-01-01
          • 1970-01-01
          • 2013-01-03
          • 2012-05-05
          • 1970-01-01
          • 1970-01-01
          • 2018-09-23
          相关资源
          最近更新 更多