swift-snippet's People
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
任意のCGRectに任意の文字列を表示できる最大のフォントSizeを計算する
systtemfontで "textextexx"
という文字列をCGSize(200,100)に表示する時
fotsizeがn以下なら潰れずに表示できる
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.