GithubHelp home page GithubHelp logo

swift-snippet's People

Contributors

churabou avatar

Watchers

 avatar

swift-snippet's Issues

SnapKitで作るUISegmentControllのスクロールするメニュービュー

class SegmentMenuView: BaseView {

    private var segment = UISegmentedControl(items: ["segment","full", "mmm"])
    
    fileprivate var scrollView = UIScrollView()
    fileprivate var childViews: [UIView] = []
    
    override func initializeView() {
        
        let v1 = UIView()
        v1.backgroundColor = .red
        let v2 = UIView()
        v2.backgroundColor = .orange
        let v3 = UIView()
        v3.backgroundColor = .green
        childViews = [v1, v2, v3]
        
        segment.tintColor = .red
        segment.addTarget(self, action: #selector(actionSegment), for: .valueChanged)
        addSubview(segment)
        
        scrollView.isPagingEnabled = true
        scrollView.delegate = self
        addSubview(scrollView)
        
        childViews.forEach { scrollView.addSubview($0) }
    }
    
    @objc private func actionSegment(_ sender: UISegmentedControl) {
        scroll(to: sender.selectedSegmentIndex)
    }
    
    override func updateConstraints() {
        super.updateConstraints()

        segment.snp.makeConstraints { (make) in
            make.top.equalTo(5)
            make.width.equalTo(160)
            make.height.equalTo(40)
            make.centerX.equalToSuperview()
        }
        
        scrollView.snp.makeConstraints { (make) in
            make.top.equalTo(segment.snp.bottom).offset(5)
            make.left.right.bottom.equalToSuperview()
        }
        
        childViews.enumerated().forEach { index, view in
            
            view.snp.makeConstraints { (make) in
                make.top.equalToSuperview()
                make.width.height.equalToSuperview()
                
                if view == childViews.first {
                    // 最初のViewはUIScrollViewの左側に設定する
                    make.left.equalToSuperview()
                } else {
                    let pre = childViews[index-1]
                    make.left.equalTo(pre.snp.right)
                }
                // 最後のViewはUIScrollViewの右側に設定する
                if view == childViews.last {
                    make.right.equalToSuperview()
                }
            }
        }
    }
    
    func scroll(to: Int) {
        
        let x = CGFloat(to) * scrollView.bounds.width
        UIView.animate(withDuration: 0.3) {
            
            self.scrollView.contentOffset.x = x
        }
    }
}

extension SegmentMenuView: UIScrollViewDelegate {
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        
        let currentIndex = scrollView.contentOffset.x / scrollView.bounds.width
        segment.selectedSegmentIndex = Int(currentIndex)
    }
}

回転しても四隅にくっつく丸

import SnapKit


protocol CircleButtonDelegate: class {
    func didSelectCircle()
}

class DeleteCircle: UIView {
    weak var delegate: CircleButtonDelegate?
    
    private var longPress = UILongPressGestureRecognizer()
    @objc private func actionTap() {
        delegate?.didSelectCircle()
    }
    
    func configure(view: UIView, delegate: CircleButtonDelegate) {
        self.delegate = delegate
        view.superview?.addSubview(self)
        let S: CGFloat = 30
        frame.size = CGSize(width: S, height: S)
        layer.cornerRadius = S/2
        clipsToBounds = true
        backgroundColor = .green
        longPress = UILongPressGestureRecognizer(target: self, action: #selector(actionTap))
        addGestureRecognizer(longPress)
    }
}





class ViewController: UIViewController {
    
    var blue = UIView()
    
    var rotateAngle: CGFloat = 0
    let circle = DeleteCircle()
    
    
    var rect: CGRect!
    
    override func viewDidLoad() {
        
        blue.backgroundColor = .blue
        view.addSubview(blue)
        rect = CGRect(x: 100, y: 100, width: 200, height: 100)
        blue.frame = rect
        
        circle.configure(view: blue, delegate: self)
        
        let origin = blue.frame.edges.bottomLeft
        circle.frame.origin = CGPoint(x: origin.x-30/2, y: origin.y-30/2)
        print("rotate: \(rect.rotatedEdges(by: 30))")
//        blue.transform = blue.transform.rotated(by: (-30*CGFloat.pi) / 180)
    }
}



extension ViewController: CircleButtonDelegate {
    
    func didSelectCircle() {
        rotateAngle += 1
        blue.transform = blue.transform.rotated(by: (1*CGFloat.pi) / 180)
        
        let origin = rect.rotatedEdges(by: Double(-rotateAngle)).bottomLeft
        circle.frame.origin = CGPoint(x: origin.x-30/2, y: origin.y-30/2)
        
    }
}

struct Math {
    
    static func sin(_ degrees: Double) -> CGFloat {
        return CGFloat(__sinpi(degrees/180.0))
    }
    
    static func cos(_ degrees: Double) -> CGFloat {
        return CGFloat(__cospi(degrees/180.0))
    }
}

extension CGRect {
    
    struct Edge {
        var topLeft: CGPoint
        var topRight: CGPoint
        var bottomLeft: CGPoint
        var bottomRight: CGPoint
        
        
        init(_ topLeft: CGPoint,
             _ topRight: CGPoint,
             _ bottomLeft: CGPoint,
             _  bottomRight: CGPoint) {
            self.topLeft = topLeft
            self.topRight = topRight
            self.bottomLeft = bottomLeft
            self.bottomRight = bottomRight
        }
        
        func dump() {
            print("topLeft \(topLeft)")
            print("topRight \(topRight)")
            print("bottomLeft \(bottomLeft)")
            print("bottomRight \(bottomRight)")
        }
        
        mutating func inverseY() {
            self.topLeft.y *= -1
            self.topRight.y *= -1
            self.bottomLeft.y *= -1
            self.bottomRight.y *= -1
        }
    }
    
    var edges: Edge {
        let topLeft = CGPoint(x: minX, y: minY)
        let topRight = CGPoint(x: maxX, y: minY)
        let bottomLeft = CGPoint(x: minX, y: maxY)
        let bottomRight = CGPoint(x: maxX, y: maxY)
        
        return Edge(topLeft, topRight, bottomLeft, bottomRight)
    }
    
    func rotatedEdges(by: Double) -> Edge {
        
        print("最初")
        edges.dump()
        //まず中心を原点に持ってくる。
        
        var rect = self
        let dif = CGPoint(x: midX, y: midY)
        
        rect.origin.x -= dif.x
        rect.origin.y -= dif.y
        
        print("中心に持ってきた")
        rect.edges.dump()
        
        var edge = rect.edges
        
        print("座標系を修正")
        edge.inverseY()
        edge.dump()
        
        
        
        print("回転")
        
        edge.topLeft = edge.topLeft.rotate(by: by)
        edge.topRight = edge.topRight.rotate(by: by)
        edge.bottomLeft = edge.bottomLeft.rotate(by: by)
        edge.bottomRight = edge.bottomRight.rotate(by: by)
        
        edge.dump()
       
        print("元に戻す")
        edge.inverseY()
        
        edge.topLeft.diff(dif)
        edge.topRight.diff(dif)
        edge.bottomLeft.diff(dif)
        edge.bottomRight.diff(dif)
        
        edge.dump()
        
        return edge
    }
    
}

fileprivate extension CGPoint {
    
    func rotate(by: Double) -> CGPoint { //x座標
        return CGPoint(x: x * Math.cos(by) - y * Math.sin(by),
                       y: x * Math.sin(by) + y * Math.cos(by))
    }
    
    mutating func diff(_ point: CGPoint) {
        x += point.x
        y += point.y
    }
}



CIKernelでぼかし加工を試みたやつ



class BlurViewController: UIViewController {
    
    
    var image: UIImage!
    
    var imageView: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        
        self.view.backgroundColor = UIColor(white: 0.8, alpha: 0.8)
        image = UIImage(named: "chura.jpg")!
        imageView = UIImageView(image: image)
        let ratio = (self.view.frame.width-50) / image.size.width
        let size = CGSize(width: image.size.width * ratio, height: image.size.height * ratio)
        imageView.frame.size = size
        imageView.center = self.view.center
        self.view.addSubview(imageView)
        
        
        custom = MyBlurFilter()
        custom.inputImage = CIImage(image: self.image)
        custom.baseImage = CIImage(image: self.image)
        
        
        
        
    }
    
    
    func createImageFrom(ciImage: CIImage) -> UIImage{
        
        let context = CIContext(options: nil)
        let cgImage = context.createCGImage(ciImage, from: ciImage.extent)!
        return UIImage(cgImage: cgImage)
    }
    
    
    func setUpImageView(with newImage: UIImage){
        
        if let _ = self.imageView {
            self.imageView.removeFromSuperview()
            self.imageView = nil
        }
        
        imageView = UIImageView(image: newImage)
        imageView.backgroundColor = UIColor.red
        let ratio = (self.view.frame.width-50) / newImage.size.width
        let size = CGSize(width: newImage.size.width * ratio, height: newImage.size.height * ratio)
        imageView.frame.size = size
        imageView.center = self.view.center
        self.imageView.image = newImage
        self.view.addSubview(imageView)
    }
//
//    private dynamic func save(image: UIImage) {
//        UIImageWriteToSavedPhotosAlbum(image, self, #selector(saved(_: didFinishSavingWithError: contextInfo:)), nil)
//    }
//
    
    @objc private func saved(_ image: UIImage, didFinishSavingWithError error: NSError!, contextInfo: UnsafeMutableRawPointer) {
        print(contextInfo)
        if error != nil {
            print("error")
        } else {
            print("success")
        }
    }
    
    // 画面にタッチで呼ばれる
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesBegan")
        
    }
    
    // ドラッグ時に呼ばれる
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        // タッチイベントを取得
        let touchEvent = touches.first!
        
        // ドラッグ前の座標, Swift 1.2 から
        let preDx = touchEvent.previousLocation(in: self.imageView).x
        let preDy = touchEvent.previousLocation(in: self.view).y
        
        // ドラッグ後の座標
        let newDx = touchEvent.location(in: self.imageView).x
        let newDy = touchEvent.location(in: self.imageView).y
        
        if newDx > imageView.frame.width || newDx < 0 {
            print("range out x ")
            
            return
        }
        
        if newDy > imageView.frame.height || newDy < 0 {
            print("range out y")
            
            return
        }
        //let center_x = newDx / imageView.frame.width - 1
        let center_x = (newDx-(imageView.frame.width/CGFloat(2))) / imageView.frame.width
        let center_y = (newDy-(imageView.frame.height / CGFloat(2))) / imageView.frame.height
        
        
        custom.center = CIVector(x: center_x * 2, y: center_y * 2)
        let outputImage = custom.output()
        let imageFromOutput = createImageFrom(ciImage: outputImage!)
        custom.inputImage = CIImage(image: imageFromOutput)
        //custom.inputImage = outputImage//?.applying(CGAffineTransform(scaleX: 1, y: -1))//.translatedBy(x: 0, y: CGFloat(outputImage.)))
        self.setUpImageView(with: imageFromOutput)
        print("from: \([preDx, preDy])")
        print("to: \([newDx, newDy])")
    }
    
    // ドラッグ終了
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        //self.save(image: self.imageView.image!)
        print("ドラッグ終了")
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    var custom: MyBlurFilter!
    
    
    
    
}


class MyBlurFilter: CIFilter {
    
    var kernel: CIKernel!
    var inputImage: CIImage? = nil
    var baseImage: CIImage? = nil
    var center: CIVector = CIVector(x: 0, y: 0)
    
    override init() {
        super.init()
        self.kernel = createKernel()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    func output() -> CIImage? {
        if let inputImage = self.inputImage {
            let args: [AnyObject] = [inputImage as AnyObject, baseImage as AnyObject ,center as AnyObject]
            let dod = inputImage.extent.insetBy(dx: 0, dy: 0)
            return kernel.apply(extent: dod, roiCallback: { (index, rect) in
                
                return rect.insetBy(dx: 0, dy: 0)
            }, arguments: args)
        }
        return nil
    }
    
    
    private func createKernel() -> CIKernel {
        //let kernelString = self.myBlurString
        let kernelString = myBlurString
        return CIKernel(source: kernelString)!
    }
    
    var myBlurString: String {
        
        return
            "bool equalVec4(vec4 x, vec4 y){\n" +
                "    bool r = x.r == y.r;\n" +
                "    bool g = x.g == y.g;\n" +
                "    bool b = x.b == y.b;\n" +
                "    bool a = x.a == y.a;\n" +
                "    return (r && b) && (b && a); \n" +
                "}\n" +
                
                "bool inner(vec2 a, vec2 center, float r){\n" + //円の内側か判定
                "    float dis =  (center.x - a.x) * (center.x - a.x) + (center.y - a.y) * (center.y - a.y);\n" +
                "    return dis < r*r ;\n" +
                "}\n" +
                
                "vec4 avcolor(sampler image, vec2 area, float range){\n" + //その座標ブロックの平均値
                "     vec2 origin = vec2(area.x * range, area.y * range);\n" +
                "     vec3 color = vec3(0);\n" +
                "     for(float i = 0.0; i < range; i++){\n" +
                "        for(float j = 0.0; j < range; j++){\n" +
                "              vec2 xy = vec2(origin.x +i, origin.y + j);\n" +
                "              vec2 size = samplerSize(image);\n" +
                "              color += sample(image, vec2(xy.x/size.x, xy.y/size.y)).rgb;\n" +
                "        }\n" +
                "     }\n" +
                "     vec3 av = (color / float(range*range));\n" +
                "     return vec4(av,1);\n" +
                "}\n" +
                
                "kernel vec4 coreImageKernel(sampler image, sampler base, vec2 _center){\n" +
                "     float r = 50.0;\n" + //半径の大きさ
                "     vec2 size = samplerSize(image);\n" +
                "     vec2 zero = size / 2.0;\n" +
                "     vec2 center = zero + vec2(zero.x * _center.x, zero.y * _center.y);\n" +
                "     float range = 40.0;\n" + //モザイクの広さブロック
                "     vec2 xy = samplerCoord(image);\n" +
                "     vec2 xy_ = vec2(xy.x * size.x, xy.y * size.y);\n" +
                "     vec2 area = vec2(xy_.x/range,xy_.y/range);\n" +
                "     bool into = inner(xy_, center, r);\n" +
                "     vec4 src = sample(image,xy);\n" +
                "     vec4 baseSrc = sample(base,xy);\n" +
                "     vec4 blurColor = avcolor(base, area, range);\n" +
                "     if (into && equalVec4(src, baseSrc)) {\n" +
                "        return blurColor;\n" +
                "     } else{\n" +
                "        return src;\n" +
                "     }\n" +
        "}\n"
        
    }
    
    var paint: String {
        
        return
            
            
            "bool inner(vec2 a, vec2 center, float r){\n" + //円の内側か判定
                "    float dis =  (center.x - a.x) * (center.x - a.x) + (center.y - a.y) * (center.y - a.y);\n" +
                "    return dis < r*r ;\n" +
                "}\n" +
                
                
                "kernel vec4 coreImageKernel(sampler image, sampler base, vec2 _center){\n" +
                "     float r = 60.0;\n" + //半径の大きさ
                "     vec2 size = samplerSize(image);\n" +
                "     vec2 zero = size / 2.0;\n" +
                "     vec2 center = zero + vec2(zero.x * _center.x, zero.y * _center.y);\n" +
                "     float range = 40.0;\n" + //モザイクの広さブロック
                "     vec2 xy = samplerCoord(image);\n" +
                "     vec2 xy_ = vec2(xy.x * size.x, xy.y * size.y);\n" +
                "     vec2 area = vec2(xy_.x/range,xy_.y/range);\n" +
                "     bool into = inner(xy_, center, r);\n" +
                "     vec4 src = sample(image,xy);\n" +
                "     if (into) {\n" +
                "        return vec4(1,0,0.6,1);\n" +
                "     } else{\n" +
                "        return src;\n" +
                "     }\n" +
        "}\n"
        
    }
}

compose rotated text to image

    func aaa() {
        
        let imageView = UIImageView()
        imageView.frame = view.frame
        imageView.contentMode = .scaleAspectFit
        view.addSubview(imageView)
        
        let image = UIImage(named: "chura.jpg")!
        
        UIGraphicsBeginImageContextWithOptions(image.size, false, 0.0)
        
        let context = UIGraphicsGetCurrentContext()!
        
//        // 回転の中心点を移動
//        
//        context.translateBy(x: image.size.width/2, y: image.size.height/2)
//        // Y軸方向を補正
//        context.scaleBy(x: 1.0, y: -1.0)
//        // ラジアンに変換(45°回転させたい場合)
//        let radian: CGFloat = 180 * CGFloat.pi / 180.0
//        context.rotate(by: radian)
//        // 回転画像の描画
//        context.draw(image.cgImage!, in: CGRect(x: -image.size.width/2, y: -image.size.height/2, width: image.size.width, height: image.size.height))
        
        image.draw(at: .zero)
        
        
        //まず合成したいラベルを用意しました。
        let label = UILabel()
        label.text = "合成するテキスト"
        label.backgroundColor = .white
        label.textAlignment = .left
        label.font = UIFont.systemFont(ofSize: 50)
        label.textColor = .red
        
        
//        //何も考えずに描画すると
//        label.drawText(in: CGRect(x: 300, y: 300, width: 500, height: 200))
        
//        //これは座標ずらして描画するので同値
//        context.translateBy(x: 300, y: 300)
//        label.drawText(in: CGRect(x: 0, y: 0, width: 500, height: 200))

        
//        //contextを回転してから描画しても、回転の中心が左上なのであかん。
//        let radian: CGFloat = 45 * CGFloat.pi / 180.0
//        context.rotate(by: radian)
//        label.drawText(in: CGRect(x: 300, y: 300, width: 500, height: 200))
        
        //        //中心で45度回転して見たいので。
        context.translateBy(x: 550, y: 400)
        let radian: CGFloat = 45 * CGFloat.pi / 180.0
        context.rotate(by: radian)
        label.drawText(in: CGRect(x: -250, y: -100, width: 250, height: 100))
        
        let output = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        imageView.image = output
    }

day2



    func configureObserver() {
        
        viewModel.result.asObservable().bind(to: tableView.rx.items) { tableView, index, item in
            let cell = UITableViewCell()
            cell.textLabel?.text = "id: \(item.id)  name: \(item.name)"
            return cell
            }
            .disposed(by: bag)
        
        viewModel.isLoading.asObservable().subscribe(onNext: {
            print($0 ? "loading" : "finish")

        })
        .disposed(by: bag)
        
        viewModel.error.asObservable().subscribe(onNext: {
            print("エラー: \($0)")
        })
        .disposed(by: bag)
    }

coregraphics

  • draw in ;;; scaling it as needed to fit
  • draw at ;;; entir image

memo

   let bag = DisposeBag()
    button.rx
    .tap
    .subscribe { _ in
    self.actionButton()
    }.disposed(by: bag)
    let label = UILabel()
    
    let textField = UITextField()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.frame = CGRect(x: 0, y: 100, width: 300, height: 50)
        label.text = "入力がここに反映される"
        view.addSubview(label)
        
        textField.backgroundColor = .red
        textField.frame = CGRect(x: 0, y: 300, width: 200, height: 60)
        textField.addTarget(self, action: #selector(textFieldValueChanged), for: .editingChanged)
        view.addSubview(textField)

    }

    @objc func textFieldValueChanged(_ sender: UITextField) {
        label.text = sender.text
    }
        textField.rx
            .text.bind(to: label.rx.text)
            .disposed(by: bag)

textFieldのtextをlabelのtextにバインドする。
なるほど・・
label.text = "aaa"
としたけど変化ない

as observle
as driver とは

lifecycle

(1 )

        blue.backgroundColor = .blue
        view.addSubview(blue)
        
        blue.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
            make.size.equalTo(100)
        }
        blue.backgroundColor = .blue
        view.addSubview(blue)
        
        blue.frame = view.frame
        
        blue.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
            make.size.equalTo(100)
        }
        
        blue.frame = view.frame
    override func viewWillLayoutSubviews() {
        blue.frame = view.frame
    }
    
    override func viewDidLayoutSubviews() {
        blue.frame = view.frame
    }

class ViewController: UIViewController {

    private var blue = BlueView()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        blue.backgroundColor = .blue
        view.addSubview(blue)
    }
}


class BlueView: UIView {
    
    override func layoutSubviews() {
        snp.makeConstraints { (make) in
            make.center.equalToSuperview()
            make.size.equalTo(100)
        }
    }
}

why



class ViewController: UIViewController {

    private var blue = BlueView()
    private var red = RedView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        blue.backgroundColor = .blue
        red.backgroundColor = .red
        view.addSubview(blue)
        blue.addSubview(red)
    }
}


class BlueView: UIView {
    
    override func draw(_ rect: CGRect) {
        print("blue draw")
    }

    override func layoutSubviews() {
        print("blue layoutSubviews")
        snp.makeConstraints { (make) in
            make.center.equalToSuperview()
            make.size.equalTo(100)
        }
    }
}


class RedView: UIView {
    
    override func draw(_ rect: CGRect) {
        print("red draw")
    }
    
    override func layoutSubviews() {
        print("red layoutSubviews")
        snp.makeConstraints { (make) in
            make.right.equalToSuperview()
            make.centerY.equalToSuperview()
            make.size.equalTo(50)
        }
    }
}
blue layoutSubviews
blue layoutSubviews
red layoutSubviews
blue layoutSubviews
red layoutSubviews
blue layoutSubviews
red layoutSubviews
blue draw
red draw

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.