Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

여러가지 추가 및 개선 🙇 #97

Merged
merged 22 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified Encrypted/XCConfig/App/DEV.xcconfig.encrypted
Binary file not shown.
Binary file modified Encrypted/XCConfig/App/PROD.xcconfig.encrypted
Binary file not shown.
9 changes: 8 additions & 1 deletion Plugins/EnvPlugin/ProjectDescriptionHelpers/InfoPlist.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public extension Project {
],
"API_BASE_URL": "$(API_BASE_URL)",
"KAKAO_API_KEY": "$(KAKAO_API_KEY)",
"BITLY_API_KEY": "$(BITLY_API_KEY)",
"UIUserInterfaceStyle": "Light",
"NSAppTransportSecurity": [
"NSExceptionDomains": [
Expand All @@ -33,7 +34,13 @@ public extension Project {
],
]
],
"LSApplicationQueriesSchemes": ["kakaokompassauth", "kakaolink"]
"LSApplicationQueriesSchemes": [
"kakaokompassauth",
"kakaolink",
"instagram",
"instagram-stories"
],
"NSPhotoLibraryAddUsageDescription": "스크린샷을 저장하기 위해서 앨범 접근 권한이 필요합니다"
]

static let baseUrlInfoPlist: [String: InfoPlist.Value] = [
Expand Down
33 changes: 33 additions & 0 deletions Projects/Core/Sources/Utility/UI/ImageSaver.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// ImageSaver.swift
// Core
//
// Created by Young Bin on 2023/09/10.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import SwiftUI
import Photos

public class ImageSaver: NSObject {
private var completion: ((Error?) -> Void)?

public func save(_ image: UIImage, completion: @escaping (Error?) -> Void) {
UIImageWriteToSavedPhotosAlbum(image, self, #selector(saveError), nil)
self.completion = completion
}

@objc private func saveError(
_ image: UIImage,
didFinishSavingWithError error: Error?,
contextInfo: UnsafeRawPointer
) {
DispatchQueue.main.async {
if let error {
self.completion?(error)
} else {
self.completion?(nil)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import UIKit
class PinchZoomView: UIView {
weak var delegate: PinchZoomViewDelgate?

private var lastScale: CGFloat = 1

private(set) var scale: CGFloat = 0 {
didSet {
delegate?.pinchZoomView(self, didChangeScale: scale)
Expand Down Expand Up @@ -74,14 +76,15 @@ class PinchZoomView: UIView {
numberOfTouches = gesture.numberOfTouches
}

scale = gesture.scale
scale = lastScale * gesture.scale

location = gesture.location(in: self)
offset = CGSize(width: location.x - startLocation.x, height: location.y - startLocation.y)

case .ended, .cancelled, .failed:
isPinching = false
scale = 1.0
scale = scale.between(min: 0.5, max: 2.0)
lastScale = scale
anchor = .center
offset = .zero
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,45 @@ import SwiftUI

public extension View {
/// 화면을 꼬집어서 늘였다 줄였다 해보세요
///
/// 왜냐면 for fun. ``PinchZoomView`` 참고
func pinchZooming() -> some View {
self.modifier(PinchToZoomViewModifier())
}

func pinchZooming(with scale: Binding<CGFloat>) -> some View {
self.modifier(PinchToZoomGestureRecognizer(scale: scale))
}
}

struct PinchToZoomViewModifier: ViewModifier {
@State var scale: CGFloat = 1.0
@State var anchor: UnitPoint = .zero
@State var offset: CGSize = .zero
@State var isPinching: Bool = false

func body(content: Content) -> some View {
content
// .scaleEffect(scale, anchor: anchor)
.scaleEffect(scale) // Prevent glitching
.offset(offset)
.overlay(
PinchZoomViewRepresentable(
scale: $scale,
anchor: $anchor,
offset: $offset,
isPinching: $isPinching)
.opacity(0.1))
.animation(isPinching ? .none : .spring(), value: isPinching)
}
}

struct PinchToZoomGestureRecognizer: ViewModifier {
@Binding var scale: CGFloat
@State var anchor: UnitPoint = .center
@State var offset: CGSize = .zero
@State var isPinching: Bool = false

func body(content: Content) -> some View {
content
.scaleEffect(scale, anchor: anchor)
.offset(offset)
.overlay(
PinchZoomViewRepresentable(
Expand Down
26 changes: 26 additions & 0 deletions Projects/Core/Sources/Utility/UI/ReverseMask.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// ReverseMask.swift
// Core
//
// Created by Young Bin on 2023/09/10.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import SwiftUI

public extension View {
@inlinable func reverseMask<Mask: View>(
alignment: Alignment = .center,
@ViewBuilder _ mask: () -> Mask
) -> some View {
self.mask(
ZStack(alignment: .center) {
Rectangle()

mask()
.blendMode(.destinationOut)
}
.compositingGroup()
)
}
}
88 changes: 88 additions & 0 deletions Projects/Core/Sources/Utility/UI/ScreenShooter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//
// ScreenShooter.swift
// Core
//
// Created by Young Bin on 2023/09/12.
// Copyright © 2023 team.humanwave. All rights reserved.
//

import SwiftUI

public struct Screenshotter<Content: View>: UIViewControllerRepresentable {
@Binding var isTakingScreenshot: Bool
var onScreenshotTaken: (UIImage?) -> Void
let content: () -> Content

public init(
isTakingScreenshot: Binding<Bool>,
@ViewBuilder content: @escaping () -> Content,
onScreenshotTaken: @escaping (UIImage?) -> Void
) {
self._isTakingScreenshot = isTakingScreenshot
self.content = content
self.onScreenshotTaken = onScreenshotTaken
}

public func makeUIViewController(context: Context) -> UIViewController {
let viewController = UIViewController()
let hostingController = UIHostingController(rootView: content())

viewController.addChild(hostingController)
viewController.view.addSubview(hostingController.view)
hostingController.view.frame = viewController.view.bounds
hostingController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

context.coordinator.hostingController = hostingController // coordinator에 hostingController를 저장합니다.
return viewController
}

public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
context.coordinator.hostingController?.rootView = content() // rootView를 업데이트 합니다.

if isTakingScreenshot {
DispatchQueue.main.async {
let screenshot = self.takeScreenshot(of: uiViewController.view)
self.onScreenshotTaken(screenshot)
self.isTakingScreenshot = false
}
}
}

public func makeCoordinator() -> Coordinator {
return Coordinator()
}

public class Coordinator {
var hostingController: UIHostingController<Content>?
}

func takeScreenshot(of view: UIView) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.isOpaque, 0.0)
defer { UIGraphicsEndImageContext() }
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
let snapshotImage = UIGraphicsGetImageFromCurrentImageContext()
return snapshotImage
}
}

// 아직 쓸 데는 없음
public extension View {
func capture() -> UIImage? {
let targetSize = UIScreen.main.bounds.size
return capture(targetSize: targetSize)
}

func capture(targetSize: CGSize) -> UIImage? {
let controller = UIHostingController(rootView: self)
let view = controller.view

view?.bounds = CGRect(origin: .zero, size: targetSize)
view?.backgroundColor = .clear
view?.layoutIfNeeded() // Force layout

let renderer = UIGraphicsImageRenderer(size: targetSize)
return renderer.image { _ in
view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
}
}
}
68 changes: 0 additions & 68 deletions Projects/Core/Sources/Utility/UI/WebView/WebViewWarmUper.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "mypage_empty.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions Projects/Domain/Sources/Model/CirclePack/CircleData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,28 @@ extension CircleData: Identifiable {
metadata.animationId
}
}


public extension Array where Element == CircleData {
func rotate(degree: Angle) -> [CircleData] {
func formula(xPoint: CGFloat, yPoint: CGFloat) -> (x: CGFloat, y: CGFloat) {
let degree = CGFloat(degree.degrees)
let newXPoint = xPoint * cos(degree) - yPoint * sin(degree)
let newYPoint = yPoint * cos(degree) + xPoint * sin(degree)

return (newXPoint, newYPoint)
}

return self.map { data in
let newCoordinate = formula(xPoint: data.xPoint, yPoint: data.yPoint)
let newCircle = CircleData(
color: data.color,
xPoint: newCoordinate.x,
yPoint: newCoordinate.y,
radius: data.radius,
metadata: data.metadata)

return newCircle
}
}
}
2 changes: 1 addition & 1 deletion Projects/Domain/Sources/Model/KeymeWebModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ import Foundation

public struct KeymeWebViewModel: Codable, Equatable {
public let matchRate: Float
public let resultCode: String
public let resultCode: String?
public let testResultId: Int
}
Loading