Git Hub
коротко
Ctrl + ↑ Позднее

Трюк использования #function

6 июня 2017, 18:27

UserDefaults

let isInstalledErlier = UserDefaults.standard.bool(forKey: "isInstalledErlier") ?? false
        
        if isInstalledErlier {
            
            UserDefaults.standard.set(true, forKey: "isInstalledErlier")
        }

Если создать расширение для UserDefaults

extension UserDefaults {
    var isInstalledErlier: Bool {
        get { return bool(forKey: #function) }
        set { set(newValue, forKey: #function) }
    }
}

то использовать будет проще

if UserDefaults.standard.isInstalledErlier == false {
            // тут какой-то полезный код
            UserDefaults.standard.isInstalledErlier = true
        }

Пример

extension UserDefaults {
    var firstLaunch: Bool {
        get { return bool(forKey: #function) }
        set { set(newValue, forKey: #function) }
    }
}
extension UserDefaults {
    var isActivated: Bool {
        get { return bool(forKey: #function) }
        set { set(newValue, forKey: #function) }
    }
    
    var appName: String {
        get { return string(forKey: #function)! }
        set { set(newValue, forKey: #function) }
    }    
}
UserDefaults.standard.appName = "Tinder"

(Обсуждение) Вопросы собеседований на Junior Developer

3 июня 2017, 13:59

Темы для собеседований:

  1. Простые типы и алгоритмы работы с ними
  2. Многопоточность (MultiThreading)
  3. Жизненный цикл MVC
  4. Runloop
  5. CoreData

Простые типы и алгоритмы работы с ними

обычно, эта тема называется Структуры данных и алгоритмы

Связанный список
Стек
Очередь

Вопросы и ответы

RxSwift

1 июня 2017, 0:04

RxGesture

labelView.rx
            .anyGesture(.longPress())
            .when(.began)
            .subscribe(onNext: {_ in
            //react to long Press
                UIView.animate(withDuration: 1, animations: {
                    self.labelView.bounds.size.width = 200
                }, completion: { ok in
                    self.labelView.bounds.size = self.sizeOfButton
                })
                print("long press")
        }).addDisposableTo(disposeBag)

UISwitch

var uiDone = UISwitch()

        uiDone.rx.isOn
            .subscribe(onNext: { isOn in
                print( isOn ? "it's ON" : "it's OFF" )
                
                try! self.uiRealm.write { ()->Void in
                    self.taskModel.isCompleted = isOn
                }
                
            }).addDisposableTo(disposeBag)

RunLoop

31 мая 2017, 11:22

Run loop делает две вещи

  1. ожидает пока что-то не произойдёт.
  2. отправляет сообщение к получателю.

Несколько интересных моментов про таймер

  1. runloop к которому ты добавляешь таймер держит на него сильную ссылку (то есть тебе не обязательно локально складывать таймер в strong property).
  2. Таймер ретейнит свой таргет (тот у которого он будет вызывать селектор).
  3. запуск в бекграунде. Селектор таймера не вызывается т. к. на background queue другой ранлуп
  4. интересный момент про таймер, чтобы запустить его не на мейн потоке надо сперва стартануть ранлуп
  5. scheduledTimerWithTimeInterval добавляет таймер в существующий ранлуп главного треда, не надо ничего стартовать

Ссылки по теме:
http://macbug.ru/cocoa/mthreadrunloops
https://habrahabr.ru/post/199130/

UIPanGestureRecognizer PanGesture

28 мая 2017, 20:08

вот и всё что нужно чтобы повесить PanGesture программно, просто пишем его кодом

func setupGestures(){
        let pan = UIPanGestureRecognizer(target: self, action: #selector(actionPan(_:)))
        scaleView.addGestureRecognizer(pan)
    }

сам обработчик касания

func actionPan(_ sender:UIPanGestureRecognizer){
        let moving = sender.translation(in: self)
        print("Pan Action: \(moving)")
        let toPoint = CGPoint(x: scaleView.center.x + moving.x, y: scaleView.center.y + moving.y)
    
        scaleView.center = toPoint
        sender.setTranslation(CGPoint(x: 0, y: 0), in: self)   
    }

@discardableResult

28 мая 2017, 19:27

полезный модификатор возвращаемого типа, если не всегда хотим получать warning при вызове функции, не обрабатывая её результат

@discardableResult func getItem(x:Int) -> Int {
        return x*x
    }
getItem()

пример кода с CocoaHeads Май 2017 Alexander Zimin

21 мая 2017, 13:08
protocol CellViewAnyModel {
  static var cellAnyType: UIView.Type { get }
  func setupAny(cell: UIView)
}

protocol CellViewModel: CellViewAnyModel {
  associatedtype CellType: UIView
  func setup(cell: CellType)
}

extension CellViewModel {
  static var cellAnyType: UIView.Type {
    return CellType.self
  }

  func setupAny(cell: UIView) {
    if let cell = cell as? CellType {
      setup(cell: cell)
    } else {
      assertionFailure("Wrong usage")
    }
  }
}

extension UITableView {
    func dequeueReusableCell(withModel model: CellViewAnyModel, for indexPath: IndexPath) -> UITableViewCell {
        let indetifier = String(describing: type(of: model).cellAnyType)
        let cell = self.dequeueReusableCell(withIdentifier: indetifier, for: indexPath)
        
        model.setupAny(cell: cell)
        return cell
    }
    
    func register(nibModels: [CellViewAnyModel.Type]) {
        for model in nibModels {
            let identifier = String(describing: model.cellAnyType)
            let nib = UINib(nibName: identifier, bundle: nil)
            self.register(nib, forCellReuseIdentifier: identifier)
        }
    }
    
}

Как получить имя класса из статического метода ?

20 мая 2017, 19:50

вариант 1

через рефлексию

static func getEntityName() -> String {
        return String(describing: Mirror(reflecting: self).subjectType).components(separatedBy: ".").first!
    }

вариант 2

немного устаревший вариант

static func getEntityName() -> String {
        return NSStringFromClass(self).components(separatedBy: ".").last!
    }

Kotlin: Шпоргалка

20 мая 2017, 18:59

Пишем в лог (logcat)

Log.d("Core", "OK\n")

ChemNote

14 мая 2017, 22:14

Chemical Note — Приложение для химиков

Это своего рода блокнот для:

  1. записи химический реакций
  2. подсчёта энерго-баланса
  3. моделирования реакций
  4. обмена наработками между химиками ;)

Кодогенерация — это просто

11 мая 2017, 12:23

Sourcery

Пример файла настроек для генерации

sources:
  - src/
templates:
  - Templates/
output:
  out/
args:

у ключей sources и templates обязательно должны стоять символы 

В качестве шаблонизатора используется Stencil

для кастомизации имён генерируемых файлов можно использовать спец теги // sourcery:file:

// sourcery:file:TemplateName.swift
 ... какой-то наш код
// sourcery:end

пример:

// sourcery:file:TemplateName.swift
// template of UIView

import UIKit

class EventModelView: UIView, EventProtocol {
	
}

// sourcery:end
// sourcery:file:Views/TemplateName2.swift
// template of UIView

import UIKit

class EventModelView2: UIView, EventProtocol {
	
}

// sourcery:end

UI по мотивам Марсианин

11 мая 2017, 1:17

Анимация мерцания

func blinkAnimation(){
        UIView.animate(withDuration: 1.0, delay: 1.0, options: .repeat, animations: {
            self.uiMission.alpha = 0
        }, completion: nil)
    }

Parallax Effect with Motion Device

8 мая 2017, 14:54

Формула Parallax

var parallaxImageHeight: CGFloat {
let maxOffset = (sqrt( cellHeight * cellHeight + 4 * parallaxSpeed * self.tableView.frame.height) - cellHeight) / 2
return maxOffset + self.cellHeight
}

TableViewCell animation

8 мая 2017, 14:48

SpriteKit

8 мая 2017, 14:42

hitTest

8 мая 2017, 0:40

Задача

У вас есть UIView c N количеством кнопок внутри
и вот прикол, высота этой вьюхи 1 пиксель,
а теперь вопрос как вы обработаете Tap'ы по каждой из кнопок ?

решение 1

//MARK: hitTest
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        if buttonOne.frame.contains(point){
                return buttonOne
        } else if buttonOne.frame.contains(point){
        return buttonTwo
} else if buttonOne.frame.contains(point){
   return buttonThree
} 
else {
 return nil
}


    }

решение 2 (более приятное)

//MARK: hitTest
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
       return  getButton(point, buttons: [buttonOne, buttonTwo, buttonThree])
    }

    func getButton(_ point:CGPoint, buttons: [UIView] ) -> UIView? {
        for button in buttons {
            if (button.frame.contains(point)){
                return button
            }
        }
        return nil
    }

GestureRecognizer

5 мая 2017, 11:29
let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        greenButton.addGestureRecognizer(singleTap)

Generamba: как использовать ?

3 мая 2017, 23:58

пример rambafile

### Headers settings
company: adeveloper

### Xcode project settings
project_name: SkillViperT
xcodeproj_path: SkillViperT.xcodeproj

### Code generation settings section
# The main project target name
project_target: SkillViperT

### 
project_file_path: SkillViperT/Modules

### Templates
templates:
#- {name: local_template_name, local: 'absolute/file/path'}
#- {name: remote_template_name, git: 'https://github.com/igrekde/remote_template'}
#- {name: catalog_template_name}
- {name: swifty_viper}

CSS для UIKit

3 мая 2017, 11:51
import UIKit


struct ButtonStyles {
    static var circle: Decoration<UIButton> {
        return { (view:UIButton) in
            let size = max(view.bounds.width, view.bounds.height)
            view.layer.cornerRadius = size/2
            view.layer.masksToBounds = true
        }
    }
}
Ctrl + ↓ Ранее