├── .gitignore ├── GTNotification ├── GTNotification.swift └── GTNotificationManager.swift ├── LICENSE ├── README.md └── SampleNotifcations ├── SampleNotifcations.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── SampleNotifcations.xccheckout │ └── xcuserdata │ │ └── mathieu.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── mathieu.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── SampleNotifcations.xcscheme │ └── xcschememanagement.plist ├── SampleNotifcations ├── AppDelegate.swift ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── LaunchImage.launchimage │ │ ├── Contents.json │ │ ├── Default-568h@2x.png │ │ ├── Default-667h@2x.png │ │ ├── Default@2x.png │ │ └── Default@3x.png │ └── notification.imageset │ │ ├── Contents.json │ │ ├── notification.png │ │ ├── notification@2x.png │ │ └── notification@3x.png ├── Info.plist └── ViewController.swift └── SampleNotifcationsTests ├── Info.plist └── SampleNotifcationsTests.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | #Mac OS 21 | # 22 | .DS_Store 23 | 24 | # Other 25 | # 26 | *.[oa] 27 | .hg. 28 | svn 29 | CVS 30 | *.psd 31 | *.xcuserstate 32 | -------------------------------------------------------------------------------- /GTNotification/GTNotification.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GTNotification.swift 3 | // An in app notification banner for Swift. 4 | // 5 | // Version 0.1 6 | // 7 | // Created by Mathieu White on 2015-06-20. 8 | // Copyright (c) 2015 Mathieu White. All rights reserved. 9 | // 10 | 11 | import UIKit 12 | 13 | @objc protocol GTNotificationDelegate: NSObjectProtocol 14 | { 15 | /** 16 | Tells the delegate that the notification has been dismissed 17 | and is no longer visible on the application's window. 18 | 19 | :param: notification the notification object that was dismissed 20 | */ 21 | optional func notificationDidDismiss(notification: GTNotification) 22 | 23 | /** 24 | Asks the delegate for the font that should be used to display 25 | the title on the notification. 26 | 27 | :param: notification the object requesting a font for its title 28 | 29 | :returns: the font for the notitifcation's title 30 | */ 31 | optional func notificationFontForTitleLabel(notification: GTNotification) -> UIFont 32 | 33 | /** 34 | Asks the delegate for the font that should be used to display 35 | the message on the notification. 36 | 37 | :param: notification the object requesting a font for its message 38 | 39 | :returns: the font for the notitifcation's message 40 | */ 41 | optional func notificationFontForMessageLabel(notification: GTNotification) -> UIFont 42 | } 43 | 44 | /** 45 | A GTNotification object specifies the properties of the 46 | notification to display on the application's window. 47 | */ 48 | class GTNotification: NSObject 49 | { 50 | /// The title of the notification 51 | var title: String = "Sample Notification" 52 | 53 | /// The message of the notification 54 | var message: String = "This is a sample notification." 55 | 56 | /// The color of the notifiation background. If blurEnabled is true, the color will be ignored. The default color is white 57 | var backgroundColor: UIColor = UIColor.whiteColor() 58 | 59 | /// The color of the text and image of the notification. The default value is black 60 | var tintColor: UIColor = UIColor.blackColor() 61 | 62 | /// The image icon for the notification 63 | weak var image: UIImage? 64 | 65 | /// True if the notification should blur the content it convers, false otherwise. The default value is false 66 | var blurEnabled: Bool = false { 67 | didSet { 68 | if (self.blurEnabled == true) 69 | { 70 | self.blurEffectStyle = UIBlurEffectStyle.Light 71 | } 72 | } 73 | } 74 | 75 | /// The blur effect style of the notification when blurEnabled is true. The default value is Light. 76 | var blurEffectStyle: UIBlurEffectStyle? 77 | 78 | /// The duration the notification should be displayed for. The default duration is 3 seconds 79 | var duration: NSTimeInterval = 3.0 80 | 81 | /// The position of the notification when presented on the window. The default position is Top 82 | var position: GTNotificationPosition = GTNotificationPosition.Top 83 | 84 | /// The animation of the notification when presented. The default animation is Fade 85 | var animation: GTNotificationAnimation = GTNotificationAnimation.Fade 86 | 87 | /// The action to be performed when the notification is dismissed manually 88 | var action: Selector? 89 | 90 | /// The target object to which the action message is sent 91 | var target: AnyObject? 92 | 93 | /// The delegate of the GTNotification 94 | weak var delegate: GTNotificationDelegate? 95 | 96 | /** 97 | Adds a target and action for a particular event to an interal dispatch table. 98 | 99 | :param: target the target object to which the action message is sent 100 | :param: action a selector identifying an action message 101 | */ 102 | func addTarget(target: AnyObject, action: Selector) 103 | { 104 | self.target = target 105 | self.action = action 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /GTNotification/GTNotificationManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GTNotificationManager.swift 3 | // An in app notification banner for Swift. 4 | // 5 | // Version 0.1 6 | // 7 | // Created by Mathieu White on 2015-06-20. 8 | // Copyright (c) 2015 Mathieu White. All rights reserved. 9 | // 10 | 11 | import UIKit 12 | 13 | /// Identifies the position of the GTNotificationView when presented on the window 14 | enum GTNotificationPosition: UInt 15 | { 16 | case Top 17 | case Bottom 18 | } 19 | 20 | /// Identifies the animation of the GTNotificationView when presenting 21 | enum GTNotificationAnimation: UInt 22 | { 23 | case Fade 24 | case Slide 25 | } 26 | 27 | /** 28 | The GTNotificationViewDelegate protocol defines an optional method to receive 29 | user touches on objects. 30 | */ 31 | @objc private protocol GTNotificationViewDelegate: NSObjectProtocol 32 | { 33 | /** 34 | Tells the delegate the notification view was tapped. 35 | 36 | :param: notificationView the GTNotificationView object being tapped 37 | */ 38 | optional func notificationViewTapped(notificationView: GTNotificationView) 39 | } 40 | 41 | /** 42 | A GTNotificationView object specifies a GTNotification that can be 43 | displayed in the app on the key window. 44 | */ 45 | private class GTNotificationView: UIView 46 | { 47 | // MARK: - Constants 48 | 49 | /// The vertical padding of the GTNotificationView 50 | let verticalPadding: CGFloat = 20.0 51 | 52 | /// The horizontal padding of the GTNotificationView 53 | let horizontalPadding: CGFloat = 20.0 54 | 55 | /// The vertical spacing between the title and message labels 56 | let labelSpacing: CGFloat = 16.0 57 | 58 | // MARK: - Variables 59 | 60 | /// Identifies if the GTNotificationView is visible or not 61 | var isVisible: Bool = false 62 | 63 | /// The title label of the GTNotificationView 64 | weak var titleLabel: UILabel? 65 | 66 | /// The message label of the GTNotificationView 67 | weak var messageLabel: UILabel? 68 | 69 | /// The image view of the GTNotificationView 70 | weak var imageView: UIImageView? 71 | 72 | override var tintColor: UIColor? { 73 | didSet 74 | { 75 | self.titleLabel?.textColor = tintColor 76 | self.messageLabel?.textColor = tintColor 77 | self.imageView?.tintColor = tintColor 78 | } 79 | } 80 | 81 | /// The position of the GTNotificationView 82 | var position: GTNotificationPosition = GTNotificationPosition.Top 83 | 84 | /// The animation of the GTNotificationView 85 | var animation: GTNotificationAnimation = GTNotificationAnimation.Fade 86 | 87 | /// The height of the GTNotificationView 88 | var notificationViewHeight: CGFloat? 89 | 90 | /// The visual blur effect for the notification view 91 | var blurView: UIVisualEffectView? 92 | 93 | /// The top layout constraint of the GTNotificationView 94 | var topConstraint: NSLayoutConstraint? 95 | 96 | /// The bottom layout constraint of the GTNotificationView 97 | var bottomConstraint: NSLayoutConstraint? 98 | 99 | /// The tap gesture that fires the action of the notification 100 | var tapGesture: UITapGestureRecognizer? 101 | 102 | /// The delegate of the GTNotificationView 103 | weak var delegate: GTNotificationViewDelegate? 104 | 105 | // MARK: - Initialization 106 | 107 | required init(coder aDecoder: NSCoder) 108 | { 109 | super.init(coder: aDecoder) 110 | } 111 | 112 | override init(frame: CGRect) 113 | { 114 | super.init(frame: frame) 115 | 116 | self.initNotificationView() 117 | } 118 | 119 | convenience init() 120 | { 121 | self.init(frame: CGRectZero) 122 | } 123 | 124 | func initNotificationView() 125 | { 126 | // Set the default properties of the GTNotificationView 127 | self.backgroundColor = UIColor.clearColor() 128 | self.alpha = 1.0 129 | self.setTranslatesAutoresizingMaskIntoConstraints(false) 130 | 131 | // Initialize the title label for the notification view 132 | let titleLabel: UILabel = UILabel() 133 | titleLabel.font = UIFont.systemFontOfSize(16.0) 134 | titleLabel.setTranslatesAutoresizingMaskIntoConstraints(false) 135 | 136 | // Initialize the message label for the notification view 137 | let messageLabel: UILabel = UILabel() 138 | messageLabel.font = UIFont.systemFontOfSize(13.0) 139 | messageLabel.numberOfLines = 0 140 | messageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping 141 | messageLabel.setTranslatesAutoresizingMaskIntoConstraints(false) 142 | 143 | // Initialize the image view for the notification view 144 | let imageView: UIImageView = UIImageView() 145 | imageView.setTranslatesAutoresizingMaskIntoConstraints(false) 146 | 147 | // Initialize the tap gesture 148 | let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("notificationTapped")) 149 | self.addGestureRecognizer(tapGesture) 150 | 151 | // Add the labels to the notification view 152 | self.addSubview(titleLabel) 153 | self.addSubview(messageLabel) 154 | self.addSubview(imageView) 155 | 156 | // Set each label to their variable 157 | self.titleLabel = titleLabel 158 | self.messageLabel = messageLabel 159 | self.imageView = imageView 160 | self.tapGesture = tapGesture 161 | } 162 | 163 | // MARK: - Auto Layout 164 | 165 | /** 166 | This method will setup the constraints for the notification view. 167 | */ 168 | func setupConstraints() 169 | { 170 | if (self.blurView != nil) 171 | { 172 | // Layout the blur view vertically 173 | self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[_blur]|", 174 | options: NSLayoutFormatOptions(0), 175 | metrics: nil, 176 | views: ["_blur" : self.blurView!])) 177 | 178 | // Layout the blur view horizontally 179 | self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[_blur]|", 180 | options: NSLayoutFormatOptions(0), 181 | metrics: nil, 182 | views: ["_blur" : self.blurView!])) 183 | } 184 | 185 | if (self.imageView?.image != nil) 186 | { 187 | // Image Center Y 188 | self.addConstraint(NSLayoutConstraint(item: self.imageView!, 189 | attribute: NSLayoutAttribute.CenterY, 190 | relatedBy: NSLayoutRelation.Equal, 191 | toItem: self, 192 | attribute: NSLayoutAttribute.CenterY, 193 | multiplier: 1.0, 194 | constant: 0.0)) 195 | 196 | // Image Left 197 | self.addConstraint(NSLayoutConstraint(item: self.imageView!, 198 | attribute: NSLayoutAttribute.Left, 199 | relatedBy: NSLayoutRelation.Equal, 200 | toItem: self, 201 | attribute: NSLayoutAttribute.Left, 202 | multiplier: 1.0, 203 | constant: self.horizontalPadding)) 204 | 205 | // Image Width 206 | self.addConstraint(NSLayoutConstraint(item: self.imageView!, 207 | attribute: NSLayoutAttribute.Width, 208 | relatedBy: NSLayoutRelation.Equal, 209 | toItem: nil, 210 | attribute: NSLayoutAttribute.NotAnAttribute, 211 | multiplier: 1.0, 212 | constant: 36.0)) 213 | 214 | // Image Height 215 | self.addConstraint(NSLayoutConstraint(item: self.imageView!, 216 | attribute: NSLayoutAttribute.Height, 217 | relatedBy: NSLayoutRelation.Equal, 218 | toItem: nil, 219 | attribute: NSLayoutAttribute.NotAnAttribute, 220 | multiplier: 1.0, 221 | constant: 36.0)) 222 | } 223 | 224 | // Title Label Top 225 | self.addConstraint(NSLayoutConstraint(item: self.titleLabel!, 226 | attribute: NSLayoutAttribute.Top, 227 | relatedBy: NSLayoutRelation.Equal, 228 | toItem: self, 229 | attribute: NSLayoutAttribute.Top, 230 | multiplier: 1.0, 231 | constant: self.verticalPadding)) 232 | 233 | // Title Label Left 234 | self.addConstraint(NSLayoutConstraint(item: self.titleLabel!, 235 | attribute: NSLayoutAttribute.Left, 236 | relatedBy: NSLayoutRelation.Equal, 237 | toItem: (self.imageView?.image == nil) ? self : self.imageView!, 238 | attribute: (self.imageView?.image == nil) ? NSLayoutAttribute.Left : NSLayoutAttribute.Right, 239 | multiplier: 1.0, 240 | constant: self.horizontalPadding)) 241 | 242 | // Title Label Right 243 | self.addConstraint(NSLayoutConstraint(item: self.titleLabel!, 244 | attribute: NSLayoutAttribute.Right, 245 | relatedBy: NSLayoutRelation.Equal, 246 | toItem: self, 247 | attribute: NSLayoutAttribute.Right, 248 | multiplier: 1.0, 249 | constant: -self.horizontalPadding)) 250 | 251 | // Message Label Top 252 | self.addConstraint(NSLayoutConstraint(item: self.messageLabel!, 253 | attribute: NSLayoutAttribute.Top, 254 | relatedBy: NSLayoutRelation.Equal, 255 | toItem: self.titleLabel!, 256 | attribute: NSLayoutAttribute.Baseline, 257 | multiplier: 1.0, 258 | constant: 0.0)) 259 | 260 | // Message Label Left 261 | self.addConstraint(NSLayoutConstraint(item: self.messageLabel!, 262 | attribute: NSLayoutAttribute.Left, 263 | relatedBy: NSLayoutRelation.Equal, 264 | toItem: self.titleLabel!, 265 | attribute: NSLayoutAttribute.Left, 266 | multiplier: 1.0, 267 | constant: 0.0)) 268 | 269 | // Message Label Right 270 | self.addConstraint(NSLayoutConstraint(item: self.messageLabel!, 271 | attribute: NSLayoutAttribute.Right, 272 | relatedBy: NSLayoutRelation.Equal, 273 | toItem: self.titleLabel!, 274 | attribute: NSLayoutAttribute.Right, 275 | multiplier: 1.0, 276 | constant: 0.0)) 277 | 278 | // Message Label Bottom 279 | self.addConstraint(NSLayoutConstraint(item: self.messageLabel!, 280 | attribute: NSLayoutAttribute.Bottom, 281 | relatedBy: NSLayoutRelation.Equal, 282 | toItem: self, 283 | attribute: NSLayoutAttribute.Bottom, 284 | multiplier: 1.0, 285 | constant: -self.verticalPadding)) 286 | } 287 | 288 | /** 289 | This method will layout the notification view and add it to the key window of the application. 290 | */ 291 | func layoutNotificationViewInWindow() 292 | { 293 | // Get a reference of the application window 294 | var window: UIWindow? = UIApplication.sharedApplication().keyWindow 295 | 296 | // The application has a key window 297 | if let window = window 298 | { 299 | // Add the notification view to the window 300 | window.addSubview(self) 301 | 302 | // Calculate the height of the notification view 303 | self.notificationViewHeight = self.heightForNoticationView() 304 | 305 | // Views Dictionary 306 | var viewsDict: [NSObject : AnyObject] = [NSObject : AnyObject]() 307 | viewsDict["_view"] = self 308 | 309 | // Metrics Dictionary 310 | var metricsDict: [NSObject : AnyObject] = [NSObject : AnyObject]() 311 | metricsDict["_h"] = self.notificationViewHeight 312 | 313 | // Notification View Width 314 | let notificationHorizontalConstraints: [AnyObject] = NSLayoutConstraint.constraintsWithVisualFormat("H:|[_view]|", 315 | options: NSLayoutFormatOptions(0), 316 | metrics: metricsDict, 317 | views: viewsDict) 318 | 319 | // Notification View Height 320 | let notificationVerticalConstraints: [AnyObject] = NSLayoutConstraint.constraintsWithVisualFormat("V:[_view(_h)]", 321 | options: NSLayoutFormatOptions(0), 322 | metrics: metricsDict, 323 | views: viewsDict) 324 | 325 | // Notification View Top 326 | if (self.position == GTNotificationPosition.Top) 327 | { 328 | var topConstant: CGFloat = 0.0 329 | 330 | if (self.animation == GTNotificationAnimation.Slide) 331 | { 332 | topConstant = -self.notificationViewHeight! 333 | } 334 | 335 | let topConstraint: NSLayoutConstraint = NSLayoutConstraint(item: self, 336 | attribute: NSLayoutAttribute.Top, 337 | relatedBy: NSLayoutRelation.Equal, 338 | toItem: window, 339 | attribute: NSLayoutAttribute.Top, 340 | multiplier: 1.0, 341 | constant: topConstant) 342 | 343 | window.addConstraint(topConstraint) 344 | self.topConstraint = topConstraint 345 | } 346 | 347 | // Notification View Bottom 348 | if (self.position == GTNotificationPosition.Bottom) 349 | { 350 | var bottomConstant: CGFloat = 0.0 351 | 352 | if (self.animation == GTNotificationAnimation.Slide) 353 | { 354 | bottomConstant = self.notificationViewHeight! 355 | } 356 | 357 | let bottomConstraint: NSLayoutConstraint = NSLayoutConstraint(item: self, 358 | attribute: NSLayoutAttribute.Bottom, 359 | relatedBy: NSLayoutRelation.Equal, 360 | toItem: window, 361 | attribute: NSLayoutAttribute.Bottom, 362 | multiplier: 1.0, 363 | constant: bottomConstant) 364 | 365 | window.addConstraint(bottomConstraint) 366 | self.bottomConstraint = bottomConstraint 367 | } 368 | 369 | // Add the constraints to the window 370 | window.addConstraints(notificationVerticalConstraints) 371 | window.addConstraints(notificationHorizontalConstraints) 372 | 373 | // Layout the notification view 374 | self.layoutIfNeeded() 375 | self.titleLabel?.layoutIfNeeded() 376 | self.messageLabel?.layoutIfNeeded() 377 | } 378 | else 379 | { 380 | // No key window found 381 | assertionFailure("Warning: make sure to call makeKeyAndVisible on the application's window.") 382 | } 383 | } 384 | 385 | // MARK: - Instance Methods 386 | 387 | /** 388 | This method calculates and returns the height for the notification view. 389 | 390 | :returns: the height of the notification view 391 | */ 392 | func heightForNoticationView() -> CGFloat 393 | { 394 | // Determine the maximum with of our labels 395 | let maximumLabelWidth: CGFloat = CGRectGetWidth(UIScreen.mainScreen().bounds) - (self.horizontalPadding * 2.0) 396 | 397 | // Initialize our maximum label size 398 | let maximumLabelSize: CGSize = CGSizeMake(maximumLabelWidth, CGFloat.max) 399 | 400 | // Get the height of the title label 401 | let titleLabelHeight: CGFloat = (self.titleLabel!.text! as NSString).boundingRectWithSize(maximumLabelSize, 402 | options: NSStringDrawingOptions.UsesLineFragmentOrigin, 403 | attributes: [NSFontAttributeName : self.titleLabel!.font], 404 | context: nil).height 405 | 406 | // Get the height of the message label 407 | let messageLabelHeight: CGFloat = (self.messageLabel!.text! as NSString).boundingRectWithSize(maximumLabelSize, 408 | options: NSStringDrawingOptions.UsesLineFragmentOrigin, 409 | attributes: [NSFontAttributeName : self.messageLabel!.font], 410 | context: nil).height 411 | 412 | // Return the total height, (vertical top and bottom padding + label heights + label spacing) 413 | return self.verticalPadding * 2.0 + titleLabelHeight + messageLabelHeight + self.labelSpacing 414 | } 415 | 416 | /** 417 | This method applies the notification view's visual attributes. 418 | 419 | :param: notification the notification that will be displayed 420 | */ 421 | func prepareForNotification(notification: GTNotification) 422 | { 423 | self.tintColor = notification.tintColor 424 | self.titleLabel?.text = notification.title 425 | self.messageLabel?.text = notification.message 426 | self.imageView?.image = notification.image 427 | self.position = notification.position 428 | self.animation = notification.animation 429 | 430 | // Get the font for the title label 431 | if (notification.delegate?.respondsToSelector(Selector("notificationFontForTitleLabel:")) == true) 432 | { 433 | self.titleLabel?.font = notification.delegate!.notificationFontForTitleLabel!(notification) 434 | } 435 | 436 | // Get the font for the message label 437 | if (notification.delegate?.respondsToSelector(Selector("notificationFontForMessageLabel:")) == true) 438 | { 439 | self.messageLabel?.font = notification.delegate!.notificationFontForMessageLabel!(notification) 440 | } 441 | 442 | if (notification.blurEnabled == true) 443 | { 444 | self.backgroundColor = UIColor.clearColor() 445 | 446 | // Add the blur effect to the notification view 447 | let blurEffect: UIBlurEffect = UIBlurEffect(style: notification.blurEffectStyle!) 448 | let blurView: UIVisualEffectView = UIVisualEffectView(effect: blurEffect) 449 | blurView.setTranslatesAutoresizingMaskIntoConstraints(false) 450 | self.insertSubview(blurView, atIndex: 0) 451 | self.blurView = blurView 452 | } 453 | else 454 | { 455 | self.backgroundColor = notification.backgroundColor 456 | } 457 | 458 | // Set the initial alpha to 0.0 for the fade animation 459 | if (self.animation == GTNotificationAnimation.Fade) 460 | { 461 | self.alpha = 0.0 462 | } 463 | else 464 | { 465 | self.alpha = 1.0 466 | } 467 | 468 | // Layout the view's subviews 469 | self.setupConstraints() 470 | 471 | // Layout the view in the window 472 | self.layoutNotificationViewInWindow() 473 | } 474 | 475 | /** 476 | This method animates the notification view on the application's window 477 | 478 | :param: show true if the notification view will dismiss, false otherwise 479 | :param: completion the completion closure to execute after the animation 480 | */ 481 | func animateNotification(willShow show: Bool, completion: (finished: Bool) -> Void) 482 | { 483 | // Set the animation view's visibility 484 | self.isVisible = show 485 | 486 | // The notification view should animate with a fade 487 | if (self.animation == GTNotificationAnimation.Fade) 488 | { 489 | UIView.animateWithDuration(0.4, 490 | animations: { 491 | self.alpha = (show == true) ? 1.0 : 0.0 492 | }, 493 | completion: { (finished) -> Void in 494 | completion(finished: finished) 495 | }) 496 | } 497 | 498 | // The notification view should animate with a slide 499 | if (self.animation == GTNotificationAnimation.Slide) 500 | { 501 | if (self.position == GTNotificationPosition.Top) 502 | { 503 | self.topConstraint?.constant = (show == true) ? 0.0 : -self.notificationViewHeight! 504 | } 505 | else 506 | { 507 | self.bottomConstraint?.constant = (show == true) ? 0.0 : self.notificationViewHeight! 508 | } 509 | 510 | UIView.animateWithDuration(0.4, 511 | animations: { 512 | self.layoutIfNeeded() 513 | }, 514 | completion: {(finished) -> Void in 515 | completion(finished: finished) 516 | }) 517 | } 518 | } 519 | 520 | // MARK: - Gesture Recognizer Methods 521 | 522 | /** 523 | This method fires when the notification view is tapped. 524 | 525 | NOTE: Tapping the notification view will dismiss it immediately. 526 | */ 527 | @objc private func notificationTapped() 528 | { 529 | // Notify the delegate that the notification view was tapped 530 | if (self.delegate?.respondsToSelector(Selector("notificationViewTapped:")) == true) 531 | { 532 | self.delegate!.notificationViewTapped!(self) 533 | } 534 | } 535 | } 536 | 537 | class GTNotificationManager: NSObject, GTNotificationViewDelegate 538 | { 539 | // MARK: - Variables 540 | 541 | /// The singleton instance of the GTNotificationManager 542 | static var sharedInstance: GTNotificationManager = GTNotificationManager() 543 | 544 | /// The private array of notifications queued for display 545 | private var mutableNotifications: [GTNotification] = [] 546 | 547 | /// The current notification view being displayed 548 | private var currentNotificationView: GTNotificationView? 549 | 550 | /// The timer that fires the scheduled dismissal of the notification 551 | private var dismissalTimer: NSTimer? 552 | 553 | // MARK: - Read Only 554 | 555 | /// The array of notifications queued for display 556 | internal var notifications: [GTNotification] { 557 | get { 558 | let immutableNotifications = self.mutableNotifications 559 | return immutableNotifications 560 | } 561 | } 562 | 563 | // MARK: - Initializers 564 | 565 | override init() 566 | { 567 | super.init() 568 | } 569 | 570 | // MARK: - Instance Methods 571 | 572 | /** 573 | This method shows the notification on the application's window. 574 | 575 | :param: notification the notification to display 576 | */ 577 | func showNotification(notification: GTNotification) 578 | { 579 | // Only show one notification at a time 580 | if (self.currentNotificationView == nil) 581 | { 582 | // Queue the notification for display 583 | self.mutableNotifications.append(notification) 584 | 585 | // Initialize a GTNotificationView 586 | let notificationView: GTNotificationView = GTNotificationView() 587 | notificationView.delegate = self 588 | 589 | // Prepare the view for the notification to display 590 | notificationView.prepareForNotification(notification) 591 | 592 | // Animate the notification 593 | notificationView.animateNotification(willShow: true, completion: {(finished: Bool) -> Void in 594 | 595 | // Schedule the notification view's dismissal 596 | self.dismissalTimer = NSTimer.scheduledTimerWithTimeInterval(notification.duration, 597 | target: self, 598 | selector: Selector("dismissCurrentNotification:"), 599 | userInfo: notification, 600 | repeats: false) 601 | 602 | }) 603 | 604 | // Set the current notification 605 | self.currentNotificationView = notificationView 606 | } 607 | } 608 | 609 | /** 610 | This method dismissed the current notification on the application's window. 611 | */ 612 | @objc private func dismissCurrentNotification(timer: NSTimer?) 613 | { 614 | var notification: GTNotification? = timer?.userInfo as? GTNotification 615 | 616 | self.dismissalTimer?.invalidate() 617 | self.dismissalTimer = nil 618 | 619 | if let notificationView = self.currentNotificationView 620 | { 621 | // Animate the notification 622 | notificationView.animateNotification(willShow: false, completion: {(finished: Bool) -> Void in 623 | 624 | // Notify the delegate of the notification's dismissal 625 | if let notification = notification 626 | { 627 | if (notification.delegate?.respondsToSelector(Selector("notificationDidDismiss:")) == true) 628 | { 629 | notification.delegate!.notificationDidDismiss!(notification) 630 | } 631 | } 632 | 633 | notificationView.removeFromSuperview() 634 | self.currentNotificationView = nil 635 | 636 | }) 637 | } 638 | } 639 | 640 | // MARK: - GTNotificationViewDelegate Methods 641 | 642 | @objc private func notificationViewTapped(notificationView: GTNotificationView) 643 | { 644 | let notification = self.mutableNotifications.removeAtIndex(0) 645 | 646 | self.dismissCurrentNotification(nil) 647 | 648 | if 649 | let target: AnyObject = notification.target, 650 | let action = notification.action 651 | { 652 | if (target.respondsToSelector(action) == true) 653 | { 654 | dispatch_after(DISPATCH_TIME_NOW, dispatch_get_main_queue(), { 655 | NSThread.detachNewThreadSelector(action, toTarget: target, withObject: nil) 656 | }) 657 | } 658 | } 659 | } 660 | } 661 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Mathieu White 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GTNotification 2 | An in-app notification banner for Swift. 3 | 4 | **Example** 5 | 6 | ``` swift 7 | // Initialize a notification 8 | let notification: GTNotification = GTNotification() 9 | notification.title = "Welcome Notification" 10 | notification.message = "Thank you for checking out GTNotificationView." 11 | notification.position = GTNotificationPosition.Top 12 | notification.animation = GTNotificationAnimation.Slide 13 | notification.blurEnabled = true 14 | 15 | // Perform a custom selector on tap 16 | notification.addTarget(self, action: Selector("dismissNotification")) 17 | 18 | // Set the notification's delegate 19 | notification.delegate = self 20 | 21 | // Show the notification 22 | GTNotificationManager.sharedInstance.showNotification(notification) 23 | ``` 24 | 25 | **GTNotificationDelegate Methods** 26 | ```swift 27 | // MARK: GTNotificationDelegate Methods 28 | 29 | func notificationDidDismiss(notification: GTNotification) 30 | { 31 | // The notification was dismissed automatically 32 | NSLog("The notification was dismissed automatically") 33 | } 34 | 35 | func notificationFontForTitleLabel(notification: GTNotification) -> UIFont 36 | { 37 | return UIFont(name: "AvenirNext-Medium", size: 16.0)! 38 | } 39 | 40 | func notificationFontForMessageLabel(notification: GTNotification) -> UIFont 41 | { 42 | return UIFont(name: "AvenirNext-Regular", size: 13.0)! 43 | } 44 | ``` 45 | 46 | **Screenshots** 47 | 48 | *Dark Blur* 49 | 50 | ![Dark Blur Notification](https://raw.githubusercontent.com/MathieuWhite/GTNotification/screenshots/Screenshots/Dark%20Blur.png) 51 | 52 | *Light Blur* 53 | 54 | ![Light Blur Notification](https://raw.githubusercontent.com/MathieuWhite/GTNotification/screenshots/Screenshots/Light%20Blur.png) 55 | 56 | *Extra Light Blur* 57 | 58 | ![Extra Light Blur Notification](https://raw.githubusercontent.com/MathieuWhite/GTNotification/screenshots/Screenshots/Extra%20Light%20Blur.png) 59 | 60 | *Solid Color* 61 | 62 | ![Solid Color Notification](https://raw.githubusercontent.com/MathieuWhite/GTNotification/screenshots/Screenshots/Solid%20Color.png) 63 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4E1ED5F51B38EA4000BE8EAB /* GTNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E1ED5F41B38EA4000BE8EAB /* GTNotification.swift */; }; 11 | 4ECC19FA1B3740A10034B572 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECC19F91B3740A10034B572 /* AppDelegate.swift */; }; 12 | 4ECC19FC1B3740A10034B572 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECC19FB1B3740A10034B572 /* ViewController.swift */; }; 13 | 4ECC1A011B3740A10034B572 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4ECC1A001B3740A10034B572 /* Images.xcassets */; }; 14 | 4ECC1A101B3740A10034B572 /* SampleNotifcationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECC1A0F1B3740A10034B572 /* SampleNotifcationsTests.swift */; }; 15 | 4ECC1A1B1B37442C0034B572 /* GTNotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECC1A1A1B37442C0034B572 /* GTNotificationManager.swift */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXContainerItemProxy section */ 19 | 4ECC1A0A1B3740A10034B572 /* PBXContainerItemProxy */ = { 20 | isa = PBXContainerItemProxy; 21 | containerPortal = 4ECC19EC1B3740A10034B572 /* Project object */; 22 | proxyType = 1; 23 | remoteGlobalIDString = 4ECC19F31B3740A10034B572; 24 | remoteInfo = SampleNotifcations; 25 | }; 26 | /* End PBXContainerItemProxy section */ 27 | 28 | /* Begin PBXFileReference section */ 29 | 4E1ED5F41B38EA4000BE8EAB /* GTNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GTNotification.swift; path = ../GTNotification/GTNotification.swift; sourceTree = ""; }; 30 | 4ECC19F41B3740A10034B572 /* SampleNotifcations.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleNotifcations.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 4ECC19F81B3740A10034B572 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 32 | 4ECC19F91B3740A10034B572 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33 | 4ECC19FB1B3740A10034B572 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 34 | 4ECC1A001B3740A10034B572 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 35 | 4ECC1A091B3740A10034B572 /* SampleNotifcationsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleNotifcationsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 36 | 4ECC1A0E1B3740A10034B572 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 37 | 4ECC1A0F1B3740A10034B572 /* SampleNotifcationsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleNotifcationsTests.swift; sourceTree = ""; }; 38 | 4ECC1A1A1B37442C0034B572 /* GTNotificationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GTNotificationManager.swift; path = ../GTNotification/GTNotificationManager.swift; sourceTree = ""; }; 39 | /* End PBXFileReference section */ 40 | 41 | /* Begin PBXFrameworksBuildPhase section */ 42 | 4ECC19F11B3740A10034B572 /* Frameworks */ = { 43 | isa = PBXFrameworksBuildPhase; 44 | buildActionMask = 2147483647; 45 | files = ( 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | 4ECC1A061B3740A10034B572 /* Frameworks */ = { 50 | isa = PBXFrameworksBuildPhase; 51 | buildActionMask = 2147483647; 52 | files = ( 53 | ); 54 | runOnlyForDeploymentPostprocessing = 0; 55 | }; 56 | /* End PBXFrameworksBuildPhase section */ 57 | 58 | /* Begin PBXGroup section */ 59 | 4ECC19EB1B3740A10034B572 = { 60 | isa = PBXGroup; 61 | children = ( 62 | 4ECC19F61B3740A10034B572 /* SampleNotifcations */, 63 | 4ECC1A0C1B3740A10034B572 /* SampleNotifcationsTests */, 64 | 4ECC19F51B3740A10034B572 /* Products */, 65 | ); 66 | sourceTree = ""; 67 | }; 68 | 4ECC19F51B3740A10034B572 /* Products */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 4ECC19F41B3740A10034B572 /* SampleNotifcations.app */, 72 | 4ECC1A091B3740A10034B572 /* SampleNotifcationsTests.xctest */, 73 | ); 74 | name = Products; 75 | sourceTree = ""; 76 | }; 77 | 4ECC19F61B3740A10034B572 /* SampleNotifcations */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 4ECC1A191B37442C0034B572 /* GTNotification */, 81 | 4ECC19F91B3740A10034B572 /* AppDelegate.swift */, 82 | 4ECC19FB1B3740A10034B572 /* ViewController.swift */, 83 | 4ECC1A001B3740A10034B572 /* Images.xcassets */, 84 | 4ECC19F71B3740A10034B572 /* Supporting Files */, 85 | ); 86 | path = SampleNotifcations; 87 | sourceTree = ""; 88 | }; 89 | 4ECC19F71B3740A10034B572 /* Supporting Files */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 4ECC19F81B3740A10034B572 /* Info.plist */, 93 | ); 94 | name = "Supporting Files"; 95 | sourceTree = ""; 96 | }; 97 | 4ECC1A0C1B3740A10034B572 /* SampleNotifcationsTests */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 4ECC1A0F1B3740A10034B572 /* SampleNotifcationsTests.swift */, 101 | 4ECC1A0D1B3740A10034B572 /* Supporting Files */, 102 | ); 103 | path = SampleNotifcationsTests; 104 | sourceTree = ""; 105 | }; 106 | 4ECC1A0D1B3740A10034B572 /* Supporting Files */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 4ECC1A0E1B3740A10034B572 /* Info.plist */, 110 | ); 111 | name = "Supporting Files"; 112 | sourceTree = ""; 113 | }; 114 | 4ECC1A191B37442C0034B572 /* GTNotification */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 4E1ED5F41B38EA4000BE8EAB /* GTNotification.swift */, 118 | 4ECC1A1A1B37442C0034B572 /* GTNotificationManager.swift */, 119 | ); 120 | name = GTNotification; 121 | path = ../../GTNotificationView; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 4ECC19F31B3740A10034B572 /* SampleNotifcations */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 4ECC1A131B3740A10034B572 /* Build configuration list for PBXNativeTarget "SampleNotifcations" */; 130 | buildPhases = ( 131 | 4ECC19F01B3740A10034B572 /* Sources */, 132 | 4ECC19F11B3740A10034B572 /* Frameworks */, 133 | 4ECC19F21B3740A10034B572 /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = SampleNotifcations; 140 | productName = SampleNotifcations; 141 | productReference = 4ECC19F41B3740A10034B572 /* SampleNotifcations.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | 4ECC1A081B3740A10034B572 /* SampleNotifcationsTests */ = { 145 | isa = PBXNativeTarget; 146 | buildConfigurationList = 4ECC1A161B3740A10034B572 /* Build configuration list for PBXNativeTarget "SampleNotifcationsTests" */; 147 | buildPhases = ( 148 | 4ECC1A051B3740A10034B572 /* Sources */, 149 | 4ECC1A061B3740A10034B572 /* Frameworks */, 150 | 4ECC1A071B3740A10034B572 /* Resources */, 151 | ); 152 | buildRules = ( 153 | ); 154 | dependencies = ( 155 | 4ECC1A0B1B3740A10034B572 /* PBXTargetDependency */, 156 | ); 157 | name = SampleNotifcationsTests; 158 | productName = SampleNotifcationsTests; 159 | productReference = 4ECC1A091B3740A10034B572 /* SampleNotifcationsTests.xctest */; 160 | productType = "com.apple.product-type.bundle.unit-test"; 161 | }; 162 | /* End PBXNativeTarget section */ 163 | 164 | /* Begin PBXProject section */ 165 | 4ECC19EC1B3740A10034B572 /* Project object */ = { 166 | isa = PBXProject; 167 | attributes = { 168 | LastUpgradeCheck = 0630; 169 | ORGANIZATIONNAME = "Mathieu White"; 170 | TargetAttributes = { 171 | 4ECC19F31B3740A10034B572 = { 172 | CreatedOnToolsVersion = 6.3.2; 173 | }; 174 | 4ECC1A081B3740A10034B572 = { 175 | CreatedOnToolsVersion = 6.3.2; 176 | TestTargetID = 4ECC19F31B3740A10034B572; 177 | }; 178 | }; 179 | }; 180 | buildConfigurationList = 4ECC19EF1B3740A10034B572 /* Build configuration list for PBXProject "SampleNotifcations" */; 181 | compatibilityVersion = "Xcode 3.2"; 182 | developmentRegion = English; 183 | hasScannedForEncodings = 0; 184 | knownRegions = ( 185 | en, 186 | Base, 187 | ); 188 | mainGroup = 4ECC19EB1B3740A10034B572; 189 | productRefGroup = 4ECC19F51B3740A10034B572 /* Products */; 190 | projectDirPath = ""; 191 | projectRoot = ""; 192 | targets = ( 193 | 4ECC19F31B3740A10034B572 /* SampleNotifcations */, 194 | 4ECC1A081B3740A10034B572 /* SampleNotifcationsTests */, 195 | ); 196 | }; 197 | /* End PBXProject section */ 198 | 199 | /* Begin PBXResourcesBuildPhase section */ 200 | 4ECC19F21B3740A10034B572 /* Resources */ = { 201 | isa = PBXResourcesBuildPhase; 202 | buildActionMask = 2147483647; 203 | files = ( 204 | 4ECC1A011B3740A10034B572 /* Images.xcassets in Resources */, 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | }; 208 | 4ECC1A071B3740A10034B572 /* Resources */ = { 209 | isa = PBXResourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | }; 215 | /* End PBXResourcesBuildPhase section */ 216 | 217 | /* Begin PBXSourcesBuildPhase section */ 218 | 4ECC19F01B3740A10034B572 /* Sources */ = { 219 | isa = PBXSourcesBuildPhase; 220 | buildActionMask = 2147483647; 221 | files = ( 222 | 4ECC1A1B1B37442C0034B572 /* GTNotificationManager.swift in Sources */, 223 | 4E1ED5F51B38EA4000BE8EAB /* GTNotification.swift in Sources */, 224 | 4ECC19FC1B3740A10034B572 /* ViewController.swift in Sources */, 225 | 4ECC19FA1B3740A10034B572 /* AppDelegate.swift in Sources */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | 4ECC1A051B3740A10034B572 /* Sources */ = { 230 | isa = PBXSourcesBuildPhase; 231 | buildActionMask = 2147483647; 232 | files = ( 233 | 4ECC1A101B3740A10034B572 /* SampleNotifcationsTests.swift in Sources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | /* End PBXSourcesBuildPhase section */ 238 | 239 | /* Begin PBXTargetDependency section */ 240 | 4ECC1A0B1B3740A10034B572 /* PBXTargetDependency */ = { 241 | isa = PBXTargetDependency; 242 | target = 4ECC19F31B3740A10034B572 /* SampleNotifcations */; 243 | targetProxy = 4ECC1A0A1B3740A10034B572 /* PBXContainerItemProxy */; 244 | }; 245 | /* End PBXTargetDependency section */ 246 | 247 | /* Begin XCBuildConfiguration section */ 248 | 4ECC1A111B3740A10034B572 /* Debug */ = { 249 | isa = XCBuildConfiguration; 250 | buildSettings = { 251 | ALWAYS_SEARCH_USER_PATHS = NO; 252 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 253 | CLANG_CXX_LIBRARY = "libc++"; 254 | CLANG_ENABLE_MODULES = YES; 255 | CLANG_ENABLE_OBJC_ARC = YES; 256 | CLANG_WARN_BOOL_CONVERSION = YES; 257 | CLANG_WARN_CONSTANT_CONVERSION = YES; 258 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 259 | CLANG_WARN_EMPTY_BODY = YES; 260 | CLANG_WARN_ENUM_CONVERSION = YES; 261 | CLANG_WARN_INT_CONVERSION = YES; 262 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 263 | CLANG_WARN_UNREACHABLE_CODE = YES; 264 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 265 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 266 | COPY_PHASE_STRIP = NO; 267 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 268 | ENABLE_STRICT_OBJC_MSGSEND = YES; 269 | GCC_C_LANGUAGE_STANDARD = gnu99; 270 | GCC_DYNAMIC_NO_PIC = NO; 271 | GCC_NO_COMMON_BLOCKS = YES; 272 | GCC_OPTIMIZATION_LEVEL = 0; 273 | GCC_PREPROCESSOR_DEFINITIONS = ( 274 | "DEBUG=1", 275 | "$(inherited)", 276 | ); 277 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 278 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 279 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 280 | GCC_WARN_UNDECLARED_SELECTOR = YES; 281 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 282 | GCC_WARN_UNUSED_FUNCTION = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 285 | MTL_ENABLE_DEBUG_INFO = YES; 286 | ONLY_ACTIVE_ARCH = YES; 287 | SDKROOT = iphoneos; 288 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 289 | }; 290 | name = Debug; 291 | }; 292 | 4ECC1A121B3740A10034B572 /* Release */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | ALWAYS_SEARCH_USER_PATHS = NO; 296 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 297 | CLANG_CXX_LIBRARY = "libc++"; 298 | CLANG_ENABLE_MODULES = YES; 299 | CLANG_ENABLE_OBJC_ARC = YES; 300 | CLANG_WARN_BOOL_CONVERSION = YES; 301 | CLANG_WARN_CONSTANT_CONVERSION = YES; 302 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 303 | CLANG_WARN_EMPTY_BODY = YES; 304 | CLANG_WARN_ENUM_CONVERSION = YES; 305 | CLANG_WARN_INT_CONVERSION = YES; 306 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 307 | CLANG_WARN_UNREACHABLE_CODE = YES; 308 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 309 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 310 | COPY_PHASE_STRIP = NO; 311 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 312 | ENABLE_NS_ASSERTIONS = NO; 313 | ENABLE_STRICT_OBJC_MSGSEND = YES; 314 | GCC_C_LANGUAGE_STANDARD = gnu99; 315 | GCC_NO_COMMON_BLOCKS = YES; 316 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 317 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 318 | GCC_WARN_UNDECLARED_SELECTOR = YES; 319 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 320 | GCC_WARN_UNUSED_FUNCTION = YES; 321 | GCC_WARN_UNUSED_VARIABLE = YES; 322 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 323 | MTL_ENABLE_DEBUG_INFO = NO; 324 | SDKROOT = iphoneos; 325 | VALIDATE_PRODUCT = YES; 326 | }; 327 | name = Release; 328 | }; 329 | 4ECC1A141B3740A10034B572 /* Debug */ = { 330 | isa = XCBuildConfiguration; 331 | buildSettings = { 332 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 333 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 334 | INFOPLIST_FILE = SampleNotifcations/Info.plist; 335 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 336 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 337 | PRODUCT_NAME = "$(TARGET_NAME)"; 338 | }; 339 | name = Debug; 340 | }; 341 | 4ECC1A151B3740A10034B572 /* Release */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 345 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 346 | INFOPLIST_FILE = SampleNotifcations/Info.plist; 347 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 348 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 349 | PRODUCT_NAME = "$(TARGET_NAME)"; 350 | }; 351 | name = Release; 352 | }; 353 | 4ECC1A171B3740A10034B572 /* Debug */ = { 354 | isa = XCBuildConfiguration; 355 | buildSettings = { 356 | BUNDLE_LOADER = "$(TEST_HOST)"; 357 | FRAMEWORK_SEARCH_PATHS = ( 358 | "$(SDKROOT)/Developer/Library/Frameworks", 359 | "$(inherited)", 360 | ); 361 | GCC_PREPROCESSOR_DEFINITIONS = ( 362 | "DEBUG=1", 363 | "$(inherited)", 364 | ); 365 | INFOPLIST_FILE = SampleNotifcationsTests/Info.plist; 366 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 367 | PRODUCT_NAME = "$(TARGET_NAME)"; 368 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleNotifcations.app/SampleNotifcations"; 369 | }; 370 | name = Debug; 371 | }; 372 | 4ECC1A181B3740A10034B572 /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | buildSettings = { 375 | BUNDLE_LOADER = "$(TEST_HOST)"; 376 | FRAMEWORK_SEARCH_PATHS = ( 377 | "$(SDKROOT)/Developer/Library/Frameworks", 378 | "$(inherited)", 379 | ); 380 | INFOPLIST_FILE = SampleNotifcationsTests/Info.plist; 381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SampleNotifcations.app/SampleNotifcations"; 384 | }; 385 | name = Release; 386 | }; 387 | /* End XCBuildConfiguration section */ 388 | 389 | /* Begin XCConfigurationList section */ 390 | 4ECC19EF1B3740A10034B572 /* Build configuration list for PBXProject "SampleNotifcations" */ = { 391 | isa = XCConfigurationList; 392 | buildConfigurations = ( 393 | 4ECC1A111B3740A10034B572 /* Debug */, 394 | 4ECC1A121B3740A10034B572 /* Release */, 395 | ); 396 | defaultConfigurationIsVisible = 0; 397 | defaultConfigurationName = Release; 398 | }; 399 | 4ECC1A131B3740A10034B572 /* Build configuration list for PBXNativeTarget "SampleNotifcations" */ = { 400 | isa = XCConfigurationList; 401 | buildConfigurations = ( 402 | 4ECC1A141B3740A10034B572 /* Debug */, 403 | 4ECC1A151B3740A10034B572 /* Release */, 404 | ); 405 | defaultConfigurationIsVisible = 0; 406 | defaultConfigurationName = Release; 407 | }; 408 | 4ECC1A161B3740A10034B572 /* Build configuration list for PBXNativeTarget "SampleNotifcationsTests" */ = { 409 | isa = XCConfigurationList; 410 | buildConfigurations = ( 411 | 4ECC1A171B3740A10034B572 /* Debug */, 412 | 4ECC1A181B3740A10034B572 /* Release */, 413 | ); 414 | defaultConfigurationIsVisible = 0; 415 | defaultConfigurationName = Release; 416 | }; 417 | /* End XCConfigurationList section */ 418 | }; 419 | rootObject = 4ECC19EC1B3740A10034B572 /* Project object */; 420 | } 421 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/project.xcworkspace/xcshareddata/SampleNotifcations.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 206E65FC-7056-4130-AA8A-5A96CF19241E 9 | IDESourceControlProjectName 10 | SampleNotifcations 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 454B9E4165B485336A373DBEB245CBECB93C2DC3 14 | https://github.com/MathieuWhite/GTNotification.git 15 | 16 | IDESourceControlProjectPath 17 | SampleNotifcations/SampleNotifcations.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 454B9E4165B485336A373DBEB245CBECB93C2DC3 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/MathieuWhite/GTNotification.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 454B9E4165B485336A373DBEB245CBECB93C2DC3 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 454B9E4165B485336A373DBEB245CBECB93C2DC3 36 | IDESourceControlWCCName 37 | GTNotification 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/project.xcworkspace/xcuserdata/mathieu.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations.xcodeproj/project.xcworkspace/xcuserdata/mathieu.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/xcuserdata/mathieu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/xcuserdata/mathieu.xcuserdatad/xcschemes/SampleNotifcations.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations.xcodeproj/xcuserdata/mathieu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SampleNotifcations.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 4ECC19F31B3740A10034B572 16 | 17 | primary 18 | 19 | 20 | 4ECC1A081B3740A10034B572 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SampleNotifcations 4 | // 5 | // Created by Mathieu White on 2015-06-21. 6 | // Copyright (c) 2015 Mathieu White. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | 20 | let viewController: ViewController = ViewController() 21 | 22 | let window: UIWindow = UIWindow(frame: UIScreen.mainScreen().bounds) 23 | window.rootViewController = viewController 24 | window.makeKeyAndVisible() 25 | 26 | self.window = window 27 | 28 | return true 29 | } 30 | 31 | func applicationWillResignActive(application: UIApplication) { 32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 33 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 34 | } 35 | 36 | func applicationDidEnterBackground(application: UIApplication) { 37 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | func applicationWillEnterForeground(application: UIApplication) { 42 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 43 | } 44 | 45 | func applicationDidBecomeActive(application: UIApplication) { 46 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 47 | } 48 | 49 | func applicationWillTerminate(application: UIApplication) { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "736h", 7 | "filename" : "Default@3x.png", 8 | "minimum-system-version" : "8.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "extent" : "full-screen", 14 | "idiom" : "iphone", 15 | "subtype" : "667h", 16 | "filename" : "Default-667h@2x.png", 17 | "minimum-system-version" : "8.0", 18 | "orientation" : "portrait", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "orientation" : "portrait", 23 | "idiom" : "iphone", 24 | "extent" : "full-screen", 25 | "minimum-system-version" : "7.0", 26 | "filename" : "Default@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "extent" : "full-screen", 31 | "idiom" : "iphone", 32 | "subtype" : "retina4", 33 | "filename" : "Default-568h@2x.png", 34 | "minimum-system-version" : "7.0", 35 | "orientation" : "portrait", 36 | "scale" : "2x" 37 | } 38 | ], 39 | "info" : { 40 | "version" : 1, 41 | "author" : "xcode" 42 | } 43 | } -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default@2x.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/LaunchImage.launchimage/Default@3x.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "notification.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "notification@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "notification@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/notification.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/notification@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/notification@2x.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/notification@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MathieuWhite/GTNotification/58899adad510ba5970d5b67919444ac6335a0252/SampleNotifcations/SampleNotifcations/Images.xcassets/notification.imageset/notification@3x.png -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.mathieuwhite.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UIStatusBarStyle 30 | UIStatusBarStyleDefault 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcations/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SampleNotifcations 4 | // 5 | // Created by Mathieu White on 2015-06-21. 6 | // Copyright (c) 2015 Mathieu White. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController, GTNotificationDelegate 12 | { 13 | override func viewDidLoad() 14 | { 15 | super.viewDidLoad() 16 | 17 | self.view.backgroundColor = UIColor.whiteColor() 18 | 19 | // Notification Button 20 | let button: UIButton = UIButton.buttonWithType(UIButtonType.System) as! UIButton 21 | button.setTitle("Show Notification", forState: UIControlState.Normal) 22 | button.setTranslatesAutoresizingMaskIntoConstraints(false) 23 | button.addTarget(self, action: Selector("notificationButtonPressed"), forControlEvents: UIControlEvents.TouchUpInside) 24 | 25 | self.view.addSubview(button) 26 | 27 | // Center the button vertically 28 | self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[_super]-(<=1)-[_btn]", 29 | options: NSLayoutFormatOptions.AlignAllCenterY, 30 | metrics: nil, 31 | views: ["_super" : self.view, "_btn" : button])) 32 | 33 | // Center the button horizontally 34 | self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[_super]-(<=1)-[_btn]", 35 | options: NSLayoutFormatOptions.AlignAllCenterX, 36 | metrics: nil, 37 | views: ["_super" : self.view, "_btn" : button])) 38 | } 39 | 40 | override func didReceiveMemoryWarning() 41 | { 42 | super.didReceiveMemoryWarning() 43 | // Dispose of any resources that can be recreated. 44 | } 45 | 46 | 47 | func notificationButtonPressed() 48 | { 49 | // Initialize a notification 50 | let notification: GTNotification = GTNotification() 51 | notification.image = UIImage(named: "notification")?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) 52 | notification.blurEnabled = true 53 | notification.blurEffectStyle = UIBlurEffectStyle.Dark 54 | notification.tintColor = UIColor.whiteColor() 55 | notification.animation = GTNotificationAnimation.Slide 56 | notification.delegate = self 57 | 58 | // Add a selector to perform on tap 59 | notification.addTarget(self, action: Selector("dismissNotification")) 60 | 61 | // Show the notification 62 | GTNotificationManager.sharedInstance.showNotification(notification) 63 | } 64 | 65 | func dismissNotification() 66 | { 67 | NSLog("The notification was dismissed manually") 68 | 69 | let alertController: UIAlertController = UIAlertController(title: "", 70 | message: "Thank you for checking out GTNotification.", 71 | preferredStyle: UIAlertControllerStyle.Alert) 72 | 73 | let dismissAction: UIAlertAction = UIAlertAction(title: "Dismiss", 74 | style: UIAlertActionStyle.Default) { (alert) -> Void in 75 | alertController.dismissViewControllerAnimated(true, completion: nil) 76 | } 77 | 78 | alertController.addAction(dismissAction) 79 | 80 | self.presentViewController(alertController, animated: true, completion: nil) 81 | } 82 | 83 | // MARK: GTNotificationDelegate Methods 84 | 85 | func notificationDidDismiss(notification: GTNotification) 86 | { 87 | // The notification was dismissed automatically 88 | NSLog("The notification was dismissed automatically") 89 | } 90 | 91 | func notificationFontForTitleLabel(notification: GTNotification) -> UIFont 92 | { 93 | return UIFont(name: "AvenirNext-Medium", size: 16.0)! 94 | } 95 | 96 | func notificationFontForMessageLabel(notification: GTNotification) -> UIFont 97 | { 98 | return UIFont(name: "AvenirNext-Regular", size: 13.0)! 99 | } 100 | 101 | } 102 | 103 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcationsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.mathieuwhite.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SampleNotifcations/SampleNotifcationsTests/SampleNotifcationsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SampleNotifcationsTests.swift 3 | // SampleNotifcationsTests 4 | // 5 | // Created by Mathieu White on 2015-06-21. 6 | // Copyright (c) 2015 Mathieu White. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class SampleNotifcationsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | --------------------------------------------------------------------------------