AppMetric для macOS
Сделал за пару вечеров простой информер для macOS, который показывает статистику по приложениям из сервиса AppMetrica от Яндекса. Висит знаком в статус баре:
- Выводит список всех приложений из AppMetrica.
- Показывает количество пользователей, сессий и крэшей за сегодня.
- Автоматически обновляет статистику в фоновом режиме.
Блок (замыкание) как свойство класса в Swift
Пример использования блока (замыкания) как свойства класса в Swift.
class ChatViewController: UIViewController {
private var someClosure: (() -> Void)?
private var anotherClosure: ((arg: Double) -> Bool)?
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: 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:
Update 2024. Swift 5.5+
Если нужна задержка внутри async-функции:func someMethod() async throws {
// sleep for 2 seconds
try await Task.sleep(nanoseconds: NSEC_PER_SEC * 2)
}
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