Arm1.ru

Блок (замыкание) как свойство класса в Swift

Пример использования блока (замыкания) как свойства класса в Swift. Инициализируется как nil.

class ChatViewController: UIViewController {

  var someClosure: (() -> Void)! // nil
  var anotherClosure: ((arg: Double) -> Bool)! // nil

  func executeClosures() {
    if self.someClosure != nil {
      self.someClosure()
    }

    if self.anotherClosure != nil {
      let boolResult = self.anotherClosure(arg: 2.0)
    }
  }

  func addSelfClosure(closure: (() -> Void)!) {
    self.someClosure = closure
  }

  func printSomething() {
    self.addSelfClosure() {
      print("closure called")
    }
    self.executeClosures() // prints: closure called
  }

}

comment comments

CompareShots v1.2

Вышло обновление CompareShots версии 1.2

Выпустил потому, что написал один из пользователей на почту просьбу скрывать логотип и текст после того, как выбрана картинка, т.к. иначе, если она не на полный экран, то они торчат из-за картинки или просвечивают. Попутно решил ещё прокачать приложение. Наконец-то пригодилась подписка на разные новые библиотеки. Поверх картинок теперь можно рисовать. Разными цветами и кистями разного размера. Один вечер - и такая красота :)

Загрузить

comment comments

Кастомный бейдж для UITabBarController на Swift

Шёл 2016 год, а для того, чтобы изменить цвета для бейджа внутри таба всё ещё необходимо создавать свой UI-элемент и добавлять его в таббар вручную. Работающее решение на Swift:

// MARK: - UITabBarController extension for badges
extension UITabBarController {

  /**
  Set badges

  - parameter badgeValues: values array
  */
  func setBadges(badgeValues: [Int]) {

    for view in self.tabBar.subviews {
      if view is CustomTabBadge {
        view.removeFromSuperview()
      }
    }

    for index in 0...badgeValues.count-1 {
      if badgeValues[index] != 0 {
        addBadge(index,
                 value: badgeValues[index],
                 color:UIColor.yellowColor(),
                 font: UIFont.systemFontOfSize(11)
        )
      }
    }

  }

  /**
  Add badge for tab

  - parameter index: index of tab
  - parameter value: badge value
  - parameter color: badge color
  - parameter font: badge font
  */
  func addBadge(index: Int, value: Int, color: UIColor, font: UIFont) {
    let badgeView = CustomTabBadge()

    badgeView.clipsToBounds = true
    badgeView.textColor = UIColor.whiteColor()
    badgeView.textAlignment = .Center
    badgeView.font = font
    badgeView.text = String(value)
    badgeView.backgroundColor = color
    badgeView.tag = index
    tabBar.addSubview(badgeView)

    self.positionBadges()
  }

  override public func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.tabBar.setNeedsLayout()
    self.tabBar.layoutIfNeeded()
    self.positionBadges()
  }

  /**
  Positioning
  */
  func positionBadges() {

    var tabbarButtons = self.tabBar.subviews.filter { (view: UIView) -> Bool in
      return view.userInteractionEnabled // only UITabBarButton are userInteractionEnabled
    }

    tabbarButtons = tabbarButtons.sort({ $0.frame.origin.x < $1.frame.origin.x })

    for view in self.tabBar.subviews {
      if view is CustomTabBadge {
        let badgeView = view as! CustomTabBadge
        self.positionBadge(badgeView, items:tabbarButtons, index: badgeView.tag)
      }
    }
  }

  /**
  Position for badge

  - parameter badgeView: badge view
  - parameter items: tab bar buttons array
  - parameter index: index of tab
  */
  func positionBadge(badgeView: UIView, items: [UIView], index: Int) {

    let itemView = items[index]
    let center = itemView.center

    let xOffset: CGFloat = 12
    let yOffset: CGFloat = -14
    badgeView.frame.size = CGSizeMake(17, 17)
    badgeView.center = CGPointMake(center.x + xOffset, center.y + yOffset)
    badgeView.layer.cornerRadius = badgeView.bounds.width/2
    tabBar.bringSubviewToFront(badgeView)
  }

}

/// Custom UILabel class for badge view
class CustomTabBadge: UILabel {}

comment comments

Функция задержки на Swift

Очень приятный синтаксический сахар - функция для запуска кода с задержкой через Grand Central Dispatch с помощью dispatch_after:

Swift 2:

/**
Delay function using GCD. Syntax sugar.

- parameter delay: delay in seconds
- parameter closure: closure code to execute after delay
*/
func delay(delay:Double, closure:()->()) {
  dispatch_after(
    dispatch_time(
      DISPATCH_TIME_NOW,
      Int64(delay * Double(NSEC_PER_SEC))
    ),
  dispatch_get_main_queue(), closure)
}

Swift 3:

/**
Delay function using GCD. Syntax sugar.

- parameter delay: delay in seconds
- parameter closure: closure code to execute after delay
*/
func delay(_ delay:Double, closure:()->()) {
  let when = DispatchTime.now() + delay
  DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}

Использование:

delay(0.4) {
  // код
}

comment comments

Модальный UIVIewController с прозрачностью

Шпаргалка - как запрезентить UIViewController поверх другого так, чтобы он был полупрозрачный и под ним просвечивал контент.

Выставляем в Storyboard для Segue поле Kind как "Present Modally". Для UIViewController, который показываем, выставляем цвет фона Clear Color, делаем внутри фон (картинка или другой UIView) со значением alpha, например, 0.5.

В коде:

self.performSegueWithIdentifier("segueName", sender: self)

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
  if segue.identifier == "segueName" {
    let vc = segue.destinationViewController as! YourViewController
    vc.modalPresentationStyle = .Custom
  }
}

 

comment comments

Редизайн блога

Решил поизучать, как выглядят сайты в Material Design от Google. Нашёл у них библиотеку Material Design Lite и запили его на сайт. Стало читабельнее, вроде, и из коробки адаптивный дизайн, можно читать с мобилок, да и на ретине выглядит теперь сочнее. Удобно, когда из готовых кусков можно собрать то, что тебе нравится. Результат мне нравится больше, чем то, что можно наваять, например, на Twitter Bootstrap.

Долго думал над шапкой и в итоге с любовью спёр идею у Apple с их страницы, посвящённой WWDC '16 :) запили на SVG и анимировал курсор на JS (правда, только на десктопной версии). Смотрел на Polymer, но что-то оно как-то не завелось у меня сходу, да и уже на MDL многое сделал. Идея веб-компонентов, конечно, классная, и семантически круто выглядит, но пока отложу её до более хорошей поддержки браузерами. Как-то там, есть ощущение, что всё сильно на Node.JS завязано, а переписывать его на ноду мне уже не хочется, жду новых релизов Swift, чтобы на него  переписать. 

comment comments
local_offer бложек