>
 				A69FFB8A1E7018CC0006FEE0 /* GroupDetail.storyboard */,
@@ -1290,6 +1294,7 @@
1290 1294
 			children = (
1291 1295
 				05D3A3CC22000C3900A29A20 /* GroupCoordinator.swift */,
1292 1296
 				A69FFAAB1E7004700006FEE0 /* GroupViewController.swift */,
1297
+				055EFAD6221A4DB400450AD5 /* GroupQRView.swift */,
1293 1298
 				0569F613220042AF000A75CA /* Group.storyboard */,
1294 1299
 				05D790AE1FC50E7C00469AD1 /* GroupDetail */,
1295 1300
 			);
@@ -1704,6 +1709,7 @@
1704 1709
 				053E126F21F5774700A64893 /* FadeToastAnimator.swift in Sources */,
1705 1710
 				05130FFE21CA1B39004EF1BE /* WaterfallFlowLayout.swift in Sources */,
1706 1711
 				05130FFF21CA1B39004EF1BE /* WaterfallFlowConfiguration.swift in Sources */,
1712
+				055BB53E220AEA3B009548AA /* NiblessViewController.swift in Sources */,
1707 1713
 				0513100021CA1B39004EF1BE /* CLLocationExt.swift in Sources */,
1708 1714
 				059B58AA21F83B2E00FA64C2 /* CenterConfirmItem.swift in Sources */,
1709 1715
 				05C5285E21FEB03F0090ECB5 /* ViewControllerTransitioningProxy.swift in Sources */,
@@ -1734,11 +1740,10 @@
1734 1740
 				0513100B21CA1B39004EF1BE /* UIColorExt.swift in Sources */,
1735 1741
 				05C8D21221ED7B620001E847 /* UINavigationBar+FixSpace.swift in Sources */,
1736 1742
 				05C8D21021ED7B280001E847 /* UIApplication+Swizzle.swift in Sources */,
1737
-				0513100E21CA1B39004EF1BE /* UIButtonExt.swift in Sources */,
1738 1743
 				0569F61A22014B30000A75CA /* NavigationBarProxy.swift in Sources */,
1739 1744
 				0513100F21CA1B39004EF1BE /* UIViewExt.swift in Sources */,
1740
-				053E125F21F16BA400A64893 /* ToastTextView.swift in Sources */,
1741 1745
 				0513109B21CA3915004EF1BE /* QRCodeConfiguration.swift in Sources */,
1746
+				055BB541220AEA62009548AA /* NiblessView.swift in Sources */,
1742 1747
 				0513101021CA1B39004EF1BE /* UIViewControllerExt.swift in Sources */,
1743 1748
 				0513101221CA1B39004EF1BE /* UITextFieldExt.swift in Sources */,
1744 1749
 				05C0CEF921F8567C00993DE2 /* AlertView.swift in Sources */,
@@ -1751,7 +1756,6 @@
1751 1756
 				05D3A3D02200288400A29A20 /* Storyboarded.swift in Sources */,
1752 1757
 				05C0CEFB21F85A7700993DE2 /* ActionSheetController.swift in Sources */,
1753 1758
 				05C8D21421ED8B9B0001E847 /* NavigationBackViewController.swift in Sources */,
1754
-				053E126121F16BB100A64893 /* ToastImageView.swift in Sources */,
1755 1759
 				0584FD7C21FABC1400FA1E3E /* PresentExtension.swift in Sources */,
1756 1760
 				05C8D21B21ED9A020001E847 /* UIViewController+Navigation.swift in Sources */,
1757 1761
 				0513109521CA3915004EF1BE /* QRCodeScanDelegate.swift in Sources */,
@@ -1780,7 +1784,6 @@
1780 1784
 				05C5285821FE995F0090ECB5 /* GestureRecognizerDelegate.swift in Sources */,
1781 1785
 				05130F6321C94C7A004EF1BE /* SideViewController.swift in Sources */,
1782 1786
 				05130F6421C94C7A004EF1BE /* PageViewController.swift in Sources */,
1783
-				053E126321F16EF300A64893 /* ToastContentView.swift in Sources */,
1784 1787
 			);
1785 1788
 			runOnlyForDeploymentPostprocessing = 0;
1786 1789
 		};
@@ -1866,10 +1869,11 @@
1866 1869
 				051310B621CB675A004EF1BE /* UIImageView+Kingfisher.swift in Sources */,
1867 1870
 				05130FDD21CA1B04004EF1BE /* GroupViewController.swift in Sources */,
1868 1871
 				05130FDF21CA1B04004EF1BE /* MemberCell.swift in Sources */,
1869
-				05130FE021CA1B04004EF1BE /* GroupDetailController.swift in Sources */,
1872
+				05130FE021CA1B04004EF1BE /* GroupDetailViewController.swift in Sources */,
1870 1873
 				05130FE121CA1B04004EF1BE /* GroupMemberController.swift in Sources */,
1871 1874
 				05130FE221CA1B04004EF1BE /* ChangeGroupNameController.swift in Sources */,
1872 1875
 				05130FE321CA1B04004EF1BE /* ShowGroupQRController.swift in Sources */,
1876
+				055EFAD7221A4DB400450AD5 /* GroupQRView.swift in Sources */,
1873 1877
 				05130FE421CA1B04004EF1BE /* MessageCommentAndThumbupCell.swift in Sources */,
1874 1878
 				05D3A3CD22000C3A00A29A20 /* GroupCoordinator.swift in Sources */,
1875 1879
 				05130FE521CA1B04004EF1BE /* MessageSystemCell.swift in Sources */,

BIN
PaiAi/Paiai.xcodeproj/project.xcworkspace/xcuserdata/FFIB.xcuserdatad/UserInterfaceState.xcuserstate


+ 12 - 0
PaiAi/Paiai.xcodeproj/xcuserdata/FFIB.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@@ -2,4 +2,16 @@
2 2
 <Bucket
3 3
    type = "1"
4 4
    version = "2.0">
5
+   <Breakpoints>
6
+      <BreakpointProxy
7
+         BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
8
+         <BreakpointContent
9
+            shouldBeEnabled = "Yes"
10
+            ignoreCount = "0"
11
+            continueAfterRunningActions = "No"
12
+            scope = "0"
13
+            stopOnStyle = "0">
14
+         </BreakpointContent>
15
+      </BreakpointProxy>
16
+   </Breakpoints>
5 17
 </Bucket>

+ 1 - 1
PaiAi/PaiaiDataKit/DataLayer/Repositories/GroupPhotoRepository.swift

@@ -22,7 +22,7 @@ struct GroupPhotoRepository {
22 22
         return groupPhotoRemoteAPI.loadContent()
23 23
     }
24 24
     
25
-    func upload(data: Data) -> Single<PhotoItem> {
25
+    func upload(data: Data) -> Single<[PhotoItem]> {
26 26
         return groupPhotoRemoteAPI.uploadPhoto(data: data)
27 27
     }
28 28
 }

+ 9 - 14
PaiAi/PaiaiDataKit/DataLayer/Repositories/Remote/GroupPhotoRemoteAPI.swift

@@ -19,33 +19,28 @@ struct GroupPhotoRemoteAPI {
19 19
     private func parse(_ json: JSON) -> [PhotoItem]? {
20 20
         guard let data = json["data"] as? [String: AnyObject],
21 21
             let photos = data["photos"] as? [[String: AnyObject]] else { return nil }
22
-        let dataArr = photos.compactMap { $0 }
22
+        let dataArr = photos.compactMap { $0["photos"] as? [[String: AnyObject]] }.flatMap { $0 }
23 23
         return dataArr.map { PhotoItem(json: $0) }
24 24
     }
25
-    
26
-    private func parseUpload(_ json: JSON) -> PhotoItem? {
27
-        guard let data = json["data"] as? [String: AnyObject],
28
-            let photos = data["photos"] as? [[String: AnyObject]] else { return nil }
29
-        let dataArr = photos.compactMap { $0 }
30
-        return PhotoItem(json: dataArr[0])
31
-    }
32 25
  
33 26
     func loadContent() -> Single<[PhotoItem]> {
34 27
         let resource = ContentResource<[PhotoItem]>(path: .groupPhotoList,
35 28
                                                      parameter: ["user_id": ShareUserId,
36
-                                                                 "group_id": groupId],
29
+                                                                 "group_id": groupId,
30
+                                                                 "current_id": -1],
37 31
                                                      parseJSON: parse)
38 32
         return resource.loadContent()
39 33
     }
40 34
     
41
-    func uploadPhoto(data: Data) -> Single<PhotoItem> {
42
-        let name = groupId + "" + "\(Date.timeIntervalSinceReferenceDate)"
43
-        let file = FileModel(name: name, fileData: data)
44
-        let uploadResource = UploadResource<PhotoItem>(path: .photoUpload,
35
+    func uploadPhoto(data: Data) -> Single<[PhotoItem]> {
36
+//        let name = groupId + "" + "\(Date.timeIntervalSinceReferenceDate)"
37
+        let file = FileModel(name: "photo", fileData: data)
38
+        let uploadResource = UploadResource<[PhotoItem]>(path: .photoUpload,
45 39
                                                        parameter: ["user_id": ShareUserId,
46 40
                                                                    "group_id": groupId,
41
+                                                                   "current_id": -1,
47 42
                                                                    "photo": file],
48
-                                                       parseJSON: parseUpload)
43
+                                                       parseJSON: parse)
49 44
         
50 45
         return uploadResource.upload()
51 46
     }

+ 1 - 0
PaiAi/PaiaiDataKit/DataLayer/Repositories/Remote/Reusable/NetWork/NetworkApi.swift

@@ -118,6 +118,7 @@ class NetworkApi {
118 118
     }
119 119
     
120 120
     public func upload<A: Resource>(resource: A) -> Single<A.Model> {
121
+        print(resource.parameter)
121 122
         return Single<A.Model>.create(subscribe: { (observer) in
122 123
             let request = self.session.upload(multipartFormData: { (multiPartData) in
123 124
                 for (key, value) in resource.parameter {

+ 12 - 25
PaiAi/PaiaiDataKit/PresentLayer/Group/GroupViewModel.swift

@@ -6,7 +6,6 @@
6 6
 //  Copyright © 2017年 FFIB. All rights reserved.
7 7
 //
8 8
 
9
-import Foundation
10 9
 import UIKit
11 10
 import RxSwift
12 11
 import RxCocoa
@@ -15,7 +14,6 @@ import RxDataSources
15 14
 public protocol GroupViewModelDelegate: class {
16 15
     func didSelect(_ item: PhotoItem)
17 16
     func navigateToGroupDetail()
18
-    func presentGroupQR()
19 17
 }
20 18
 
21 19
 public class GroupViewModel {
@@ -27,8 +25,6 @@ public class GroupViewModel {
27 25
     private var _isLoading = PublishSubject<Void>()
28 26
     private let items = BehaviorRelay<[PhotoItem]>(value: [])
29 27
     
30
-    public var photographBtnTapped = PublishSubject<Void>()
31
-    
32 28
     
33 29
     public var isLoading: Observable<Void> {
34 30
         return _isLoading.asObservable()
@@ -44,40 +40,36 @@ public class GroupViewModel {
44 40
     
45 41
     public init(groupItem: GroupItem) {
46 42
         self.respository = GroupPhotoRepository(groupId: groupItem.group_id)
47
-        
48
-        
49
-        photographBtnTapped.subscribe({
50
-            [weak self] (_) in
51
-            guard let `self` = self else { return }
52
-//            self.delegate?.scanQR()
53
-        }).disposed(by: disposeBag)
54 43
     }
55 44
     
56 45
     public func reload() {
57 46
         respository.load()
58 47
             .subscribe(onSuccess: {[weak self] (result) in
59
-                guard let `self` = self else { return }                
48
+                guard let `self` = self else { return }
60 49
                 self._isLoading.onNext(())
61 50
                 self.items.accept(result)
62
-                }, onError: {[weak self] (_) in
51
+                }, onError: {[weak self] (error) in
63 52
                     guard let `self` = self else { return }
64 53
                     self._isLoading.onNext(())
65 54
             }).disposed(by: disposeBag)
66 55
     }
67 56
 
68
-    public func submit(image: UIImage) {
69
-        let edge = image.size.width > image.size.height ? image.size.height : image.size.width
70
-//        let newImage = image.scaledImage(1280 / edge),
71
-        guard let data = image.jpegData(compressionQuality: 0.4) else { return }
72
-
73
-        respository.upload(data: data)
57
+    public func submit(data: Data) {
58
+        respository.upload(data: data).subscribe(onSuccess: { [weak self] result in
59
+            guard let `self` = self else { return }
60
+            self.items.accept(result)
61
+            self._isLoading.onNext(())
62
+        }) {[weak self] (error) in
63
+            guard let  `self` = self else { return }
64
+            self._isLoading.onNext(())
65
+        }.disposed(by: disposeBag)
74 66
     }
75 67
     
76 68
     public func layoutSizeForIndexPath(_ indexPath: IndexPath) -> CGSize {
77 69
         let item = items.value[indexPath.row]
78 70
         let w = item.photo_thumbnail_w
79 71
         let h = item.photo_thumbnail_h
80
-        
72
+
81 73
         //        header 42, footer: 32
82 74
         return CGSize(width: w, height: h + 74)
83 75
     }
@@ -92,9 +84,4 @@ public extension GroupViewModel {
92 84
     @objc func navigateToGroupDetail() {
93 85
         delegate?.navigateToGroupDetail()
94 86
     }
95
-    
96
-    
97
-    @objc func presentGroupQR() {
98
-        delegate?.presentGroupQR()
99
-    }
100 87
 }

+ 10 - 18
PaiAi/PaiaiUIKit/Reusable/Extension/UIKit/UIBarButtonItemExt.swift

@@ -16,7 +16,7 @@ public extension UIBarButtonItem {
16 16
     
17 17
     convenience init(image: UIImage?, target: Any, action: Selector) {
18 18
         let button = UIButton(type: .custom)
19
-        button.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
19
+        button.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
20 20
         button.setImage(image, for: .normal)
21 21
         button.addTarget(target, action: action, for: .touchDown)
22 22
         self.init(customView: button)
@@ -24,7 +24,7 @@ public extension UIBarButtonItem {
24 24
     
25 25
     convenience init(title: String, target: Any, action: Selector) {
26 26
         let button = UIButton(type: .custom)
27
-        button.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
27
+        button.frame = CGRect(x: 0, y: 0, width: 36, height: 36)
28 28
         button.setTitle(title, for: .normal)
29 29
         button.addTarget(target, action: action, for: .touchDown)
30 30
         button.sizeToFit()
@@ -36,7 +36,7 @@ public extension UIBarButtonItem {
36 36
         var lastX: CGFloat = 0
37 37
         for (title, action) in zip(titles, actions) {
38 38
             let button = UIButton(type: .custom)
39
-            button.frame = CGRect(x: lastX, y: 2, width: 40, height: 40)
39
+            button.frame = CGRect(x: lastX, y: 2, width: 36, height: 36)
40 40
             button.setTitle(title, for: .normal)
41 41
             button.addTarget(target, action: action, for: .touchDown)
42 42
             button.sizeToFit()
@@ -48,30 +48,22 @@ public extension UIBarButtonItem {
48 48
         self.init(customView: barView)
49 49
     }
50 50
     
51
-    convenience init(images: [UIImage?], btnSpace: CGFloat, target: Any, actions: [Selector]) {
51
+    convenience init(images: [UIImage?], btnSpace: CGFloat = 0, targets: [Any], actions: [Selector]) {
52 52
         let barView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: 36))
53
-        barView.backgroundColor = UIColor.cyan
54 53
         
55
-        var last: UIButton?
56
-        for (image, action) in zip(images, actions) {
54
+        var lastX: CGFloat = 0
55
+        
56
+        for (target, (image, action)) in zip(targets, zip(images, actions)) {
57 57
             let button = UIButton(type: .custom)
58
-            button.translatesAutoresizingMaskIntoConstraints = false
58
+            button.frame = CGRect(x: lastX, y: 2, width: 36, height: 36)
59 59
             button.setImage(image, for: .normal)
60 60
             button.addTarget(target, action: action, for: .touchDown)
61 61
             barView.addSubview(button)
62 62
             
63
-            NSLayoutConstraint.activate([
64
-                button.widthAnchor.constraint(equalToConstant: 36),
65
-                button.heightAnchor.constraint(equalToConstant: 36),
66
-                button.centerYAnchor.constraint(equalTo: barView.centerYAnchor),
67
-                button.leadingAnchor.constraint(equalTo: last?.trailingAnchor ?? barView.leadingAnchor)
68
-                ])
69
-            last = button
63
+            lastX += button.width + btnSpace
70 64
         }
71 65
         
72
-        if let l = last {
73
-            NSLayoutConstraint.activate([l.trailingAnchor.constraint(equalTo: barView.trailingAnchor)])
74
-        }
66
+        barView.width = lastX - btnSpace
75 67
         
76 68
         self.init(customView: barView)
77 69
     }

+ 8 - 15
PaiAi/PaiaiUIKit/Reusable/Extension/UIKit/UIImageExt.swift

@@ -11,24 +11,17 @@ import UIKit
11 11
 public extension UIImage {
12 12
     
13 13
     func scaledImage(_ scale: CGFloat) -> UIImage? {
14
-        let rect = CGRect(x: 0, y: 0, width: self.size.width * scale, height: self.size.height * scale).integral
15
-        UIGraphicsBeginImageContextWithOptions(rect.size, true, UIScreen.main.scale)
16
-        self.draw(in: rect)
17
-        let image = UIGraphicsGetImageFromCurrentImageContext()
18
-        UIGraphicsEndImageContext()
19
-        return image
14
+        let outputSize = size * scale
15
+        let renderer = UIGraphicsImageRenderer(size: outputSize)
16
+        return renderer.image(actions: {_ in })
20 17
     }
21 18
     
22
-    static func imageWithColor(_ color: UIColor) -> UIImage {
23
-        let rect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)
24
-        UIGraphicsBeginImageContext(rect.size)
25
-        let context = UIGraphicsGetCurrentContext()
26
-        context?.setFillColor(color.cgColor)
27
-        context?.fill(rect)
28
-        let image = UIGraphicsGetImageFromCurrentImageContext()
29
-        UIGraphicsEndImageContext()
30
-        return image!
19
+    func scaledImage(length: CGFloat, with quality: CGFloat) -> Data? {
20
+        let edge = size.width > size.height ? size.height : size.width
21
+        let outputSize = size * (length / edge)
31 22
         
23
+        let renderer = UIGraphicsImageRenderer(size: outputSize)
24
+        return renderer.image(actions: {_ in }).jpegData(compressionQuality: quality)
32 25
     }
33 26
 }
34 27
 

+ 3 - 3
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/ActionSheetAnimator.swift

@@ -8,8 +8,8 @@
8 8
 
9 9
 import UIKit
10 10
 
11
-struct ActionSheetAnimator: PresentAnimatable {
12
-    func contentViewAppearAnimation(duration: TimeInterval, in view: UIView) {
11
+public struct ActionSheetAnimator: PresentAnimatable {
12
+    public func contentViewAppearAnimation(duration: TimeInterval, in view: UIView) {
13 13
         let animation = CATransition()
14 14
         
15 15
         animation.duration = duration
@@ -19,7 +19,7 @@ struct ActionSheetAnimator: PresentAnimatable {
19 19
         view.layer.add(animation, forKey: nil)
20 20
     }
21 21
     
22
-    func contentViewDisappearAnimation(duration: TimeInterval, in view: UIView) {
22
+    public func contentViewDisappearAnimation(duration: TimeInterval, in view: UIView) {
23 23
         let fromValue = view.layer.position.y
24 24
         let toValue = fromValue + view.bounds.height
25 25
         

+ 6 - 3
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/AlertAnimator.swift

@@ -8,8 +8,11 @@
8 8
 
9 9
 import UIKit
10 10
 
11
-struct AlertAnimator: PresentAnimatable {
12
-    func contentViewAppearAnimation(duration: TimeInterval, in view: UIView) {
11
+public struct AlertAnimator: PresentAnimatable {
12
+    
13
+    public init() {}
14
+    
15
+    public func contentViewAppearAnimation(duration: TimeInterval, in view: UIView) {
13 16
         let animation = CABasicAnimation(keyPath: "transform.scale")
14 17
         
15 18
         animation.toValue = 1
@@ -20,7 +23,7 @@ struct AlertAnimator: PresentAnimatable {
20 23
         view.layer.add(animation, forKey: nil)
21 24
     }
22 25
     
23
-    func contentViewDisappearAnimation(duration: TimeInterval, in view: UIView) {
26
+    public func contentViewDisappearAnimation(duration: TimeInterval, in view: UIView) {
24 27
         let animation = CAKeyframeAnimation(keyPath: "transform.scale")
25 28
         
26 29
         animation.values = [1, 1.1, 0]

+ 5 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/AlertViewController.swift

@@ -12,6 +12,10 @@ import UIKit
12 12
 open class AlertViewController: UIViewController, PresentViewController {
13 13
     
14 14
     open var animationView: UIView? {
15
+        if case let .custom(alertView, _) = style {
16
+            return alertView
17
+        }
18
+        
15 19
         return nil
16 20
     }
17 21
     
@@ -29,7 +33,7 @@ open class AlertViewController: UIViewController, PresentViewController {
29 33
     
30 34
     public var animator: PresentAnimatable = AlertAnimator()
31 35
     
32
-    init(style: Style = .alert) {
36
+    public init(style: Style = .alert) {
33 37
         _style = style
34 38
         super.init(nibName: nil, bundle: nil)
35 39
         commonInit()

+ 0 - 5
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertController.swift

@@ -32,11 +32,6 @@ public class AlertController: AlertViewController {
32 32
         return alertView.confirmItem
33 33
     }
34 34
     
35
-    public override func viewDidLoad() {
36
-        super.viewDidLoad()
37
-        view.addSubview(alertView)
38
-    }
39
-    
40 35
     /// title and message is only avilable in type is alert
41 36
     public init(title: String = "", message: String = "", contentView: UIView? = nil) {
42 37
         alertView = .default

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/AlertViewController/Default/AlertView.swift

@@ -20,7 +20,7 @@ public final class AlertView: UIView {
20 20
     private var cancelAction: AlertAction?
21 21
     
22 22
     public var cancelItem: AlertItem = {
23
-        let item =  AlertItem(type: .custom)
23
+        let item = AlertItem(type: .custom)
24 24
         item.backgroundColor = UIColor(r: 214, g: 214, b: 214)
25 25
         item.setTitleColor(UIColor(r: 51, g: 51, b: 51), for: .normal)
26 26
         

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/NavigationBack/NavigationBackDelegate.swift

@@ -19,7 +19,7 @@ public extension NavigationBackDelegate where Self: UIViewController {
19 19
         btn.contentHorizontalAlignment = .left
20 20
         btn.frame = CGRect(x: 0, y: 0, width: 40 , height: 40)
21 21
         btn.setImage(UIImage(named: "navigation-back"), for: .normal)
22
-        btn.addTarget(self, action: #selector(backToViewController), for: .touchUpInside)
22
+        btn.addTarget(self, action: #selector(backToViewController), for: .touchDown)
23 23
         
24 24
         let backItem = UIBarButtonItem(customView: btn)
25 25
         let spaceItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)

+ 13 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/Nibless/NiblessView.swift

@@ -6,4 +6,16 @@
6 6
 //  Copyright © 2019 yb. All rights reserved.
7 7
 //
8 8
 
9
-import Foundation
9
+import UIKit
10
+
11
+open class NiblessView: UIView {
12
+    public override init(frame: CGRect) {
13
+        super.init(frame: frame)
14
+    }
15
+    
16
+    @available(*, unavailable, message: "Loading this view from a nib is unsupported")
17
+    public required init?(coder aDecoder: NSCoder) {
18
+        fatalError("Loading this view from a nib is unsupported")
19
+    }
20
+}
21
+

+ 12 - 16
PaiAi/PaiaiUIKit/Reusable/UIKit/Nibless/NiblessViewController.swift

@@ -8,23 +8,19 @@
8 8
 
9 9
 import UIKit
10 10
 
11
-class NiblessViewController: UIViewController {
12
-
13
-    override func viewDidLoad() {
14
-        super.viewDidLoad()
15
-
16
-        // Do any additional setup after loading the view.
11
+open class NiblessViewController: UIViewController {
12
+    /// - Methods
13
+    public init() {
14
+        super.init(nibName: nil, bundle: nil)
17 15
     }
18 16
     
19
-
20
-    /*
21
-    // MARK: - Navigation
22
-
23
-    // In a storyboard-based application, you will often want to do a little preparation before navigation
24
-    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
25
-        // Get the new view controller using segue.destination.
26
-        // Pass the selected object to the new view controller.
17
+    @available(*, unavailable, message: "Loading this view controller from a nib is unsupported")
18
+    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
19
+        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
20
+    }
21
+    
22
+    @available(*, unavailable, message: "Loading this view controller from a nib is unsupported")
23
+    public required init(coder aDecoder: NSCoder) {
24
+        fatalError("Loading this view controller from a nib is unsupported")
27 25
     }
28
-    */
29
-
30 26
 }

+ 1 - 0
PaiAi/PaiaiUIKit/Reusable/UIKit/Present/PresentAppearAnimatedTransitioning.swift

@@ -28,6 +28,7 @@ final class PresentAppearAnimatedTransitioning: NSObject, UIViewControllerAnimat
28 28
             let animationView = delegate?.animationView else { return }
29 29
 
30 30
         transitionContext.containerView.addSubview(toView)
31
+        toView.addSubview(animationView)
31 32
         
32 33
         let duration = transitionDuration(using: transitionContext)
33 34
         

+ 1 - 1
PaiAi/PaiaiUIKit/Reusable/UIKit/Present/PresentDisappearAnimatedTransitioning.swift

@@ -28,7 +28,7 @@ final class PresentDisappearAnimatedTransitioning: NSObject, UIViewControllerAni
28 28
             let toVC = transitionContext.viewController(forKey: .to),
29 29
             let toView = toVC.view,
30 30
             let animationView = delegate?.animationView else { return }
31
-
31
+                
32 32
         let duration = transitionDuration(using: transitionContext)
33 33
         
34 34
         animator.fromViewPresentingAnimation(duration: duration, in: fromView)

+ 2 - 2
PaiAi/PaiaiUIKit/Reusable/UIKit/QR/ColorQR.swift

@@ -37,7 +37,7 @@ extension NSObject {
37 37
     }
38 38
 }
39 39
 
40
-extension UIImage {
40
+public extension UIImage {
41 41
     //init with qr code string
42 42
 
43 43
     /// 初始化一个qr
@@ -45,7 +45,7 @@ extension UIImage {
45 45
     /// - Parameters:
46 46
     ///   - qr: qr携带的信息
47 47
     ///   - size: qr的大小
48
-    convenience init?(qr: String, size: CGSize?) {
48
+    convenience init?(qr: String, size: CGSize? = nil) {
49 49
 
50 50
         guard let qrImageFilter = CIFilter(name: "CIQRCodeGenerator") else {
51 51
             self.init(named: "")

+ 33 - 3
PaiAi/PaiaiUIKit/Reusable/UIKit/Toast/Toast.swift

@@ -13,9 +13,9 @@ private let globalInstance = Toast()
13 13
 public class Toast {
14 14
     public enum ToastType {
15 15
         case text(String)
16
-        case image(UIImage)
17
-        case imageWithText(UIImage, String)
18
-        case activityIndicator
16
+        case image(UIImage?)
17
+        case imageWithText(UIImage?, String)
18
+        case activityIndicator(String?)
19 19
     }
20 20
     
21 21
     public enum PresentationStyle {
@@ -64,6 +64,24 @@ public extension Toast {
64 64
         show(config: config, in: view)
65 65
     }
66 66
     
67
+    func show(image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
68
+        var config = Config()
69
+        config.toastType = .image(image)
70
+        show(config: config, in: view)
71
+    }
72
+    
73
+    func show(message: String, image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
74
+        var config = Config()
75
+        config.toastType = .imageWithText(image, message)
76
+        show(config: config, in: view)
77
+    }
78
+    
79
+    func showActivity(message: String?, in view: UIView? = UIApplication.shared.keyWindow) {
80
+        var config = Config()
81
+        config.toastType = .activityIndicator(message)
82
+        show(config: config, in: view)
83
+    }
84
+    
67 85
     func hide() {
68 86
         hideAnimation()
69 87
     }
@@ -101,6 +119,18 @@ public extension Toast {
101 119
         globalInstance.show(message: message, in: view)
102 120
     }
103 121
     
122
+    static func show(image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
123
+        globalInstance.show(image: image, in: view)
124
+    }
125
+    
126
+    static func show(message: String, image: UIImage?, in view: UIView? = UIApplication.shared.keyWindow) {
127
+        globalInstance.show(message: message, image: image, in: view)
128
+    }
129
+    
130
+    static func showActivity(message: String?, in view: UIView? = UIApplication.shared.keyWindow) {
131
+        globalInstance.showActivity(message: message, in: view)
132
+    }
133
+    
104 134
     static func hide() {
105 135
         globalInstance.hide()
106 136
     }

+ 1 - 0
PaiAi/PaiaiUIKit/Reusable/UIKit/Toast/ToastOption.swift

@@ -11,6 +11,7 @@ import Foundation
11 11
 public struct ToastOption {
12 12
     var tintColor: UIColor = UIColor.white
13 13
     var backgroundColor: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)
14
+    var font: UIFont = UIFont.systemFont(ofSize: 14)
14 15
     
15 16
     public static var `default`: ToastOption {
16 17
         return ToastOption()

+ 149 - 48
PaiAi/PaiaiUIKit/Reusable/UIKit/Toast/ToastView.swift

@@ -8,33 +8,28 @@
8 8
 
9 9
 import UIKit
10 10
 
11
-class ToastView: UIView {
11
+class ToastView: NiblessView {
12 12
     
13
-    fileprivate(set) var option: ToastOption
14
-    fileprivate(set) var toastType: Toast.ToastType = .text("")
15
-    fileprivate(set) var contentView: UIView = UIView()
13
+    fileprivate var option: ToastOption
14
+    fileprivate var toastType: Toast.ToastType
16 15
     
17
-    fileprivate var _constraints: [NSLayoutConstraint] = []
16
+    fileprivate var label: UILabel?
17
+    fileprivate var imageView: UIImageView?
18
+    fileprivate var activityIndicatorView: UIActivityIndicatorView?
18 19
     
19
-    override init(frame: CGRect) {
20
-        option = .default
21
-        super.init(frame: CGRect.zero)
22
-    }
20
+    fileprivate var text: String?
21
+    fileprivate var image: UIImage?
22
+    fileprivate var isActivity: Bool = false
23
+    
24
+    fileprivate var topView: UIView?
25
+    fileprivate var bottomView: UIView?
26
+    fileprivate var padding = UIEdgeInsets(top: 12, left: 12, bottom: 12, right: 12)
23 27
     
24
-    required init?(coder aDecoder: NSCoder) {
25
-        fatalError("init(coder:) has not been implemented")
26
-    }
27 28
     
28
-    convenience init(option: ToastOption, type: Toast.ToastType) {
29
-        self.init(frame: CGRect.zero)
29
+    init(option: ToastOption, type: Toast.ToastType) {
30 30
         self.option = option
31
-        
32
-        switch type {
33
-        case let .text(text):
34
-            contentView = ToastTextView(text: text, option: option)
35
-        default:
36
-            break
37
-        }
31
+        self.toastType = type
32
+        super.init(frame: CGRect.zero)
38 33
         
39 34
         initProperty()
40 35
     }
@@ -47,50 +42,156 @@ class ToastView: UIView {
47 42
     
48 43
     override func didMoveToWindow() {
49 44
         switch toastType {
50
-        case .text:
51
-            constructViewHierarchyText()
52
-            activateConstraintsText()
53
-        default:
54
-            break
45
+        case let .text(t):
46
+            text = t
47
+        case let .image(i):
48
+            image = i
49
+        case let .imageWithText(i, t):
50
+            image = i
51
+            text = t
52
+        case let .activityIndicator(t):
53
+            text = t
54
+            isActivity = true
55 55
         }
56
+        
57
+        constructViewHierarchy()
58
+        activateConstraints()
56 59
     }
57 60
 }
58 61
 
59
-/// text
62
+/// construct view and layout
60 63
 fileprivate extension ToastView {
61
-    func constructViewHierarchyText() {
62
-        addSubview(contentView)
64
+    
65
+    func constructViewHierarchy() {
66
+        if image != nil {
67
+            imageView = makeImageView()
68
+            addSubview(imageView!)
69
+        }
70
+        
71
+        if isActivity {
72
+            activityIndicatorView = makeActivityIndicatorView()
73
+            addSubview(activityIndicatorView!)
74
+        }
75
+        
76
+        if text != nil {
77
+            label = makeLabel()
78
+            addSubview(label!)
79
+        }
80
+    }
81
+    
82
+    func activateConstraints() {
83
+        activateConstraintsImage()
84
+        activateConstraintsIndicator()
85
+        activateConstraintsText()
86
+        activateConstraintsContentView()
87
+    }
88
+    
89
+    func activateConstraintsImage() {
90
+        guard let imageView = imageView else { return }
91
+        
92
+        imageView.translatesAutoresizingMaskIntoConstraints = false
93
+        
94
+        NSLayoutConstraint.activate([
95
+            imageView.widthAnchor.constraint(equalToConstant: 50),
96
+            imageView.heightAnchor.constraint(equalToConstant: 50),
97
+            imageView.centerXAnchor.constraint(equalTo: centerXAnchor),
98
+            imageView.topAnchor.constraint(equalTo: topAnchor, constant: padding.top)
99
+            ])
100
+        
101
+        topView = imageView
102
+    }
103
+    
104
+    func activateConstraintsIndicator() {
105
+        guard let activityIndicatorView = activityIndicatorView else { return }
106
+        
107
+        activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
108
+        
109
+        NSLayoutConstraint.activate([
110
+            activityIndicatorView.centerXAnchor.constraint(equalTo: centerXAnchor),
111
+            activityIndicatorView.topAnchor.constraint(equalTo: topAnchor, constant: padding.top)
112
+            ])
113
+        
114
+        topView = activityIndicatorView
115
+        activityIndicatorView.startAnimating()
63 116
     }
64 117
     
65 118
     func activateConstraintsText() {
66
-        activateContraintsToastView()
67
-        activateContraintsToastTextView()
119
+        guard let label = label else { return }
120
+        
121
+        let windowSize = UIScreen.main.bounds.size
122
+        
123
+        label.translatesAutoresizingMaskIntoConstraints = false
124
+        
125
+        NSLayoutConstraint.activate([
126
+            label.centerXAnchor.constraint(equalTo: centerXAnchor),
127
+            widthAnchor.constraint(lessThanOrEqualToConstant: windowSize.width - 52),
128
+            label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -padding.bottom),
129
+            label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding.left),
130
+            label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding.right),
131
+            label.topAnchor.constraint(equalTo: topView?.bottomAnchor ?? topAnchor, constant: 6),
132
+            ])
133
+        
134
+        if (text?.count ?? 0) <= 3 {
135
+            
136
+        } else {
137
+            NSLayoutConstraint.activate([
138
+                ])
139
+        }
140
+        
141
+        if topView != nil {
142
+            NSLayoutConstraint.activate([
143
+                label.widthAnchor.constraint(greaterThanOrEqualTo: heightAnchor)
144
+                ])
145
+        }
146
+        
147
+        bottomView = label
68 148
     }
69 149
     
70
-    func activateContraintsToastView() {
150
+    func activateConstraintsContentView() {
71 151
         guard let v = superview else { return }
72 152
         translatesAutoresizingMaskIntoConstraints = false
73 153
         
74 154
         NSLayoutConstraint.activate([
75
-            contentView.centerXAnchor.constraint(equalTo: v.centerXAnchor),
76
-            contentView.centerYAnchor.constraint(equalTo: v.centerYAnchor)
77
-        ])
155
+            centerXAnchor.constraint(equalTo: v.centerXAnchor),
156
+            centerYAnchor.constraint(equalTo: v.centerYAnchor)
157
+            ])
158
+        
159
+        if topView == nil {
160
+            NSLayoutConstraint.activate([
161
+                bottomView!.topAnchor.constraint(equalTo: topAnchor, constant: padding.top)
162
+                ])
163
+        } else if bottomView == nil {
164
+            NSLayoutConstraint.activate([
165
+                topView!.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -padding.bottom),
166
+                topView!.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding.left),
167
+                topView!.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding.right)
168
+                ])
169
+        }
78 170
     }
79
-    
80
-    func activateContraintsToastTextView() {
81
-        let windowSize = UIScreen.main.bounds.size
82
-        contentView.translatesAutoresizingMaskIntoConstraints = false
171
+}
172
+
173
+fileprivate extension ToastView {
174
+    func makeLabel() -> UILabel {
175
+        let l = UILabel()
176
+        l.text = text
177
+        l.numberOfLines = 0
178
+        l.font = option.font
179
+        l.textAlignment = .center
180
+        l.textColor = option.tintColor
83 181
         
84
-        let textConstraints = [
85
-            contentView.topAnchor.constraint(equalTo: topAnchor, constant: 6),
86
-            contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -6),
87
-            contentView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 6),
88
-            contentView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -6),
89
-            contentView.widthAnchor.constraint(lessThanOrEqualToConstant: windowSize.width - 40)
90
-        ]
182
+        return l
183
+    }
184
+    
185
+    func makeImageView() -> UIImageView {
186
+        let i = UIImageView()
187
+        i.image = image
91 188
         
92
-        NSLayoutConstraint.activate(textConstraints)
189
+        return i
190
+    }
191
+    
192
+    func makeActivityIndicatorView() -> UIActivityIndicatorView {
193
+        let a = UIActivityIndicatorView(style: .white)
93 194
         
94
-        _constraints += textConstraints
195
+        return a
95 196
     }
96 197
 }

+ 2 - 6
PaiAi/PaiaiUIKit/Reusable/UIKit/WebViewController.swift

@@ -9,7 +9,7 @@
9 9
 import UIKit
10 10
 import WebKit
11 11
 
12
-public class WebViewController: UIViewController {
12
+public class WebViewController: NiblessViewController {
13 13
 
14 14
     public private(set) var path: String?
15 15
     
@@ -20,15 +20,11 @@ public class WebViewController: UIViewController {
20 20
     }()
21 21
     
22 22
     public init(title: String, path: String) {
23
-        super.init(nibName: nil, bundle: nil)
23
+        super.init()
24 24
         self.title = title
25 25
         self.path = path
26 26
     }
27 27
     
28
-    required init?(coder aDecoder: NSCoder) {
29
-        fatalError("init(coder:) has not been implemented")
30
-    }
31
-    
32 28
     override public func viewDidLoad() {
33 29
         super.viewDidLoad()
34 30
         view.backgroundColor = UIColor.white

+ 24 - 3
PaiAi/Paiai_iOS/App/Group/GroupCoordinator.swift

@@ -6,14 +6,35 @@
6 6
 //  Copyright © 2019 yb. All rights reserved.
7 7
 //
8 8
 
9
-import Foundation
9
+import UIKit
10
+import PaiaiDataKit
10 11
 
11 12
 class GroupCoordinator: Coordinator {
12 13
     
13
-    var navigationController: UINavigationController
14
+    let navigationController: UINavigationController
15
+    let groupViewController: GroupViewController
14 16
     
15
-    init(navigationController: UINavigationController) {
17
+    init(_ groupVC: GroupViewController, navigationController: UINavigationController) {
18
+        self.groupViewController = groupVC
16 19
         self.navigationController = navigationController
20
+        
21
+        groupViewController.viewModel.delegate = self
22
+    }
23
+}
24
+
25
+extension GroupCoordinator: GroupViewModelDelegate {
26
+    func navigateToGroupDetail() {
27
+        
28
+    }
29
+    
30
+    func didSelect(_ item: PhotoItem) {
31
+        
32
+    }
33
+}
34
+
35
+fileprivate extension GroupCoordinator {
36
+    func makeGroupDetailViewController() {
37
+        
17 38
     }
18 39
 }
19 40
 

+ 3 - 7
PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetail.storyboard

@@ -1,10 +1,6 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="s9X-RR-Rat">
3
-    <device id="retina4_7" orientation="portrait">
4
-        <adaptation id="fullscreen"/>
5
-    </device>
6 3
     <dependencies>
7
-        <deployment identifier="iOS"/>
8 4
         <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
9 5
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
10 6
     </dependencies>
@@ -101,10 +97,10 @@
101 97
             </objects>
102 98
             <point key="canvasLocation" x="-232" y="2161.6191904047978"/>
103 99
         </scene>
104
-        <!--GroupDetailController-->
100
+        <!--GroupDetailViewController-->
105 101
         <scene sceneID="Oa4-Yi-HJu">
106 102
             <objects>
107
-                <viewController storyboardIdentifier="GroupDetailController" id="s9X-RR-Rat" userLabel="GroupDetailController" customClass="GroupDetailController" customModule="Paiai_iOS" customModuleProvider="target" sceneMemberID="viewController">
103
+                <viewController storyboardIdentifier="GroupDetailViewController" id="s9X-RR-Rat" userLabel="GroupDetailViewController" customClass="GroupDetailViewController" customModule="Paiai_iOS" customModuleProvider="target" sceneMemberID="viewController">
108 104
                     <layoutGuides>
109 105
                         <viewControllerLayoutGuide type="top" id="w38-w0-jLd"/>
110 106
                         <viewControllerLayoutGuide type="bottom" id="a7q-m3-cDV"/>
@@ -420,7 +416,7 @@
420 416
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
421 417
                         <subviews>
422 418
                             <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="cas-Ep-jsP">
423
-                                <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
419
+                                <rect key="frame" x="0.0" y="6" width="375" height="661"/>
424 420
                                 <color key="backgroundColor" red="0.94901960780000005" green="0.94901960780000005" blue="0.94901960780000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
425 421
                                 <color key="separatorColor" red="0.94117647058823528" green="0.94117647058823528" blue="0.94117647058823528" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
426 422
                                 <prototypes>

+ 11 - 1
PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetailCoordinator.swift

@@ -8,7 +8,17 @@
8 8
 
9 9
 import Foundation
10 10
 
11
-
11
+class GroupDetailCoordinator: Coordinator {
12
+    let navigationController: UINavigationController
13
+    let groupDetailViewController: GroupDetailViewController
14
+    
15
+    init(_ groupDetailVC: GroupDetailViewController, navigationController: UINavigationController) {
16
+        self.groupDetailViewController = groupDetailVC
17
+        self.navigationController = navigationController
18
+        
19
+//        groupViewController.viewModel.delegate = self
20
+    }
21
+}
12 22
 
13 23
 extension UIStoryboard {
14 24
     static var groupDetail: UIStoryboard {

+ 2 - 2
PaiAi/Paiai_iOS/App/Group/GroupDetail/GroupDetailViewController.swift

@@ -1,5 +1,5 @@
1 1
 //
2
-//  GroupDetailController.swift
2
+//  GroupDetailViewController.swift
3 3
 //  PaiAi
4 4
 //
5 5
 //  Created by zhengjianfei on 16/4/5.
@@ -12,7 +12,7 @@ import RxCocoa
12 12
 import PaiaiUIKit
13 13
 import PaiaiDataKit
14 14
 
15
-final class GroupDetailController: UIViewController {
15
+final class GroupDetailViewController: UIViewController {
16 16
 
17 17
     // MARK: Storyboard property
18 18
     @IBOutlet weak var scrollViewConstraint: NSLayoutConstraint!

+ 125 - 8
PaiAi/Paiai_iOS/App/Group/GroupQRView.swift

@@ -7,15 +7,132 @@
7 7
 //
8 8
 
9 9
 import UIKit
10
+import PaiaiUIKit
10 11
 
11
-class GroupQRView: UIView {
12
-
13
-    /*
14
-    // Only override draw() if you perform custom drawing.
15
-    // An empty implementation adversely affects performance during animation.
16
-    override func draw(_ rect: CGRect) {
17
-        // Drawing code
12
+class GroupQRView: NiblessView {
13
+    
14
+    private var groupName: String
15
+    private var groupAvatar: String
16
+    private var groupQR: String
17
+    
18
+    lazy var groupAvatarImageView: UIImageView = {
19
+        let imageView = UIImageView()
20
+        
21
+        imageView.image = UIImage(named: groupAvatar)
22
+        
23
+        return imageView
24
+    }()
25
+    
26
+    lazy var groupNameLabel: UILabel = {
27
+        let label = UILabel()
28
+        
29
+        label.text = groupName
30
+        label.font = UIFont.systemFont(ofSize: 17)
31
+        
32
+        return label
33
+    }()
34
+    
35
+    lazy var qrImageView: UIImageView = {
36
+        let imageView = UIImageView()
37
+        
38
+        imageView.image = UIImage(qr: groupQR)
39
+        
40
+        return imageView
41
+    }()
42
+    
43
+    lazy var qrLabel: UILabel = {
44
+        let label = UILabel()
45
+        
46
+        label.text = "扫描二维码加入群"
47
+        label.textColor = UIColor(gray: 153)
48
+        label.font = UIFont.systemFont(ofSize: 14)
49
+        
50
+        return label
51
+    }()
52
+    
53
+    init(groupName: String, groupAvatar: String, groupQR: String) {
54
+        self.groupName = groupName
55
+        self.groupAvatar = groupAvatar
56
+        self.groupQR = groupQR
57
+        
58
+        super.init(frame: CGRect.zero)
59
+    }
60
+    
61
+    override func didMoveToWindow() {
62
+        super.didMoveToWindow()
63
+        constructViewHierarchy()
64
+        activateConstraints()
65
+        backgroundColor = UIColor.white
66
+    }
67
+    
68
+    private func constructViewHierarchy() {
69
+        addSubview(groupAvatarImageView)
70
+        addSubview(groupNameLabel)
71
+        addSubview(qrImageView)
72
+        addSubview(qrLabel)
18 73
     }
19
-    */
74
+}
20 75
 
76
+fileprivate extension GroupQRView {
77
+    func activateConstraints() {
78
+        activateConstraintsContent()
79
+        activateConstraintsQRImageView()
80
+        activateConstraintsQRLabel()
81
+        activateConstraintsGroupAvatarImageView()
82
+        activateConstraintsGroupNameLabel()
83
+    }
84
+    
85
+    func activateConstraintsContent() {
86
+        guard let superView = superview else { return }
87
+        
88
+        translatesAutoresizingMaskIntoConstraints = false
89
+        
90
+        NSLayoutConstraint.activate([
91
+            widthAnchor.constraint(equalToConstant: 300),
92
+            centerXAnchor.constraint(equalTo: superView.centerXAnchor),
93
+            centerYAnchor.constraint(equalTo: superView.centerYAnchor)
94
+        ])
95
+    }
96
+    
97
+    func activateConstraintsGroupAvatarImageView() {
98
+        groupAvatarImageView.translatesAutoresizingMaskIntoConstraints = false
99
+        
100
+        NSLayoutConstraint.activate([
101
+            groupAvatarImageView.widthAnchor.constraint(equalToConstant: 50),
102
+            groupAvatarImageView.heightAnchor.constraint(equalToConstant: 50),
103
+            groupAvatarImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
104
+            groupAvatarImageView.topAnchor.constraint(equalTo: topAnchor, constant: 12),
105
+        ])
106
+    }
107
+    
108
+    func activateConstraintsGroupNameLabel() {
109
+        groupNameLabel.translatesAutoresizingMaskIntoConstraints = false
110
+        
111
+        NSLayoutConstraint.activate([
112
+            groupNameLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
113
+            groupNameLabel.topAnchor.constraint(equalTo: groupAvatarImageView.bottomAnchor, constant: 6)
114
+        ])
115
+        
116
+    }
117
+    
118
+    func activateConstraintsQRImageView() {
119
+        qrImageView.translatesAutoresizingMaskIntoConstraints = false
120
+        
121
+        NSLayoutConstraint.activate([
122
+            qrImageView.widthAnchor.constraint(equalToConstant: 250),
123
+            qrImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
124
+            qrImageView.widthAnchor.constraint(equalTo: qrImageView.heightAnchor),
125
+            qrImageView.topAnchor.constraint(equalTo: groupNameLabel.bottomAnchor, constant: 12),
126
+        ])
127
+    }
128
+    
129
+    func activateConstraintsQRLabel() {
130
+        qrLabel.translatesAutoresizingMaskIntoConstraints = false
131
+        
132
+        NSLayoutConstraint.activate([
133
+            qrLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
134
+            qrLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -12),
135
+            qrLabel.topAnchor.constraint(equalTo: qrImageView.bottomAnchor, constant: 6),
136
+        ])
137
+    }
21 138
 }

+ 24 - 16
PaiAi/Paiai_iOS/App/Group/GroupViewController.swift

@@ -37,7 +37,7 @@ final class GroupViewController: UIViewController {
37 37
     
38 38
     var navigationBarViewImage: UIImageView = {
39 39
         let image = UIImageView()
40
-        image.cornerRadius = 20
40
+        image.cornerRadius = 18
41 41
         return image
42 42
     }()
43 43
     
@@ -70,6 +70,7 @@ final class GroupViewController: UIViewController {
70 70
             [unowned self] in
71 71
             self.viewModel.reload()
72 72
         }
73
+        collectionView.startRefreshing(at: .top)
73 74
     }
74 75
 }
75 76
 
@@ -86,7 +87,6 @@ fileprivate extension GroupViewController {
86 87
     }
87 88
     
88 89
     func binding() {
89
-        bindInteraction()
90 90
         bindViewModelToRefreshing()
91 91
         bindCollectionViewDelegate()
92 92
         bindViewModelToCollectionView()
@@ -95,10 +95,6 @@ fileprivate extension GroupViewController {
95 95
         bindViewModelToNavigationBarTitle()
96 96
     }
97 97
     
98
-    func bindInteraction() {
99
-        photographBtn.rx.tap.bind(to: viewModel.photographBtnTapped).disposed(by: disposeBag)
100
-    }
101
-    
102 98
     func bindViewModelToRefreshing() {
103 99
         viewModel.isLoading
104 100
             .subscribe(onNext: {[unowned self] flag in
@@ -156,15 +152,23 @@ extension GroupViewController: NavigationBarInteractiveViewController {
156 152
     private func setRightBarButtonItems() {
157 153
         let item = UIBarButtonItem(images: [UIImage(named: "navigation-QR"),
158 154
                                             UIImage(named: "navigation-right")],
159
-                                   btnSpace: 6,
160
-                                   target: self,
161
-                                   actions: [#selector(viewModel!.presentGroupQR),
162
-                                             #selector(viewModel!.navigateToGroupDetail)])
155
+                                   targets: [self, viewModel],
156
+                                   actions: [#selector(GroupViewController.presentGroupQR),
157
+                                             #selector(GroupViewModel.navigateToGroupDetail)])
158
+
163 159
         navigationItem.rightBarButtonItem = item
164 160
     }
161
+    
162
+    @objc func presentGroupQR() {
163
+        let alert = AlertViewController(style: .custom(GroupQRView(groupName: groupItem.group_name,
164
+                                                                   groupAvatar: "Group\(groupItem.group_default_avatar)",
165
+                                                                   groupQR: "https:pai.ai/g/\(groupItem.group_id)"),
166
+                                                       AlertAnimator()) )
167
+        presentController(alert)
168
+    }
165 169
 }
166 170
 
167
-/// layout
171
+/// navigation bar layout
168 172
 fileprivate extension GroupViewController {
169 173
     
170 174
     func activateConstraintsNavigation() {
@@ -199,14 +203,18 @@ fileprivate extension GroupViewController {
199 203
         navigationBarViewImage.translatesAutoresizingMaskIntoConstraints = false
200 204
         
201 205
         NSLayoutConstraint.activate([
202
-            navigationBarViewImage.widthAnchor.constraint(equalToConstant: 40),
203
-            navigationBarViewImage.heightAnchor.constraint(equalToConstant: 40),
206
+            navigationBarViewImage.widthAnchor.constraint(equalToConstant: 36),
207
+            navigationBarViewImage.heightAnchor.constraint(equalToConstant: 36),
204 208
             navigationBarViewImage.centerYAnchor.constraint(equalTo: navigationBarView.centerYAnchor),
205 209
             navigationBarViewImage.leadingAnchor.constraint(equalTo: navigationBarView.leadingAnchor),
206 210
             ])
207 211
     }
208 212
 }
209 213
 
214
+extension GroupViewController {
215
+    
216
+}
217
+
210 218
 extension GroupViewController: UICollectionViewDelegateFlowLayout {
211 219
     func collectionView(_ collectionView: UICollectionView,
212 220
                         layout collectionViewLayout: UICollectionViewLayout,
@@ -231,10 +239,10 @@ extension GroupViewController: UIImagePickerControllerDelegate, UINavigationCont
231 239
 
232 240
     func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
233 241
         dismiss(animated: true, completion: nil)
242
+        guard let image = info[.originalImage] as? UIImage,
243
+            let data = image.scaledImage(length: 1280, with: 0.4) else { return }
234 244
         
235
-        guard let image = info[.originalImage] as? UIImage else { return }
236
-        
237
-        viewModel.submit(image: image)
245
+        viewModel.submit(data: data)
238 246
     }
239 247
     
240 248
     func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {

+ 1 - 1
PaiAi/Paiai_iOS/App/Home/ScanQRViewController.swift

@@ -24,7 +24,7 @@ final class ScanQRViewController: UIViewController {
24 24
     // MARK: view function
25 25
     override func viewDidLoad() {
26 26
         super.viewDidLoad()
27
-        navigationController?.navigationBar.setBackgroundImage(UIImage.imageWithColor(UIColor.black), for: .default)
27
+//        navigationController?.navigationBar.setBackgroundImage(UIImage.imageWithColor(UIColor.black), for: .default)
28 28
         scanView.delegate = self
29 29
     }
30 30
 

+ 3 - 4
PaiAi/Paiai_iOS/App/Mine/MineCoordinator.swift

@@ -60,11 +60,10 @@ extension MineCoordinator: MineViewControllerDelegate {
60 60
 
61 61
 extension MineCoordinator: MineGroupViewModelDelegate {
62 62
     func didSelect(_ item: GroupItem) {
63
-        let vc = makeGroupViewController(item: item)
64
-        let coordinator = GroupCoordinator(navigationController: navigationController)
63
+        let coordinator = GroupCoordinator(makeGroupViewController(item: item),
64
+                                           navigationController: navigationController)
65 65
         childCoordinator["group"] = coordinator
66
-        
67
-        navigationController.pushViewController(vc)
66
+        navigationController.pushViewController(coordinator.groupViewController)
68 67
     }
69 68
 }
70 69
 

+ 1 - 1
PaiAi/Paiai_iOS/App/Mine/MineViewController.swift

@@ -82,7 +82,7 @@ extension MineViewController: UITableViewDataSource {
82 82
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
83 83
         let cell = tableView.dequeueReusableCell(withIdentifier: "mineCell", for: indexPath)
84 84
         cell.textLabel?.text = menuTitle[indexPath.row]
85
-        cell.textLabel?.textColor = UIColor(r: 51, g: 51, b: 51, a: 1.0)
85
+        cell.textLabel?.textColor = UIColor(gray: 51)
86 86
         cell.imageView?.image = UIImage(named: menuImage[indexPath.row])
87 87
         
88 88
         return cell

+ 1 - 1
PaiAi/Paiai_iOS/App/PhotoDetail/ImageCell.swift

@@ -19,7 +19,7 @@ final class ImageCell: UICollectionViewCell, UIScrollViewDelegate {
19 19
         photoImage.contentMode = .scaleAspectFit
20 20
         scrollView.contentSize = size
21 21
         scrollView.addSubview(photoImage)
22
-        photoImage.image = UIImage.imageWithColor(UIColor.black)
22
+//        photoImage.image = UIImage.imageWithColor(UIColor.black)
23 23
         if !url.isEmpty {
24 24
 //            photoImage.setImageWithNullableURL(url, placeholderImage: UIImage(named: "详情页占位图"))
25 25
         } else {

kodo - Gogs: Go Git Service

暫無描述

Brightcells: 018d52f61d Update package django_xxx 8 年之前
..
migrations f724e0f9c0 Add tour guide apis 10 年之前
__init__.py f724e0f9c0 Add tour guide apis 10 年之前
admin.py f724e0f9c0 Add tour guide apis 10 年之前
models.py f724e0f9c0 Add tour guide apis 10 年之前
tests.py f724e0f9c0 Add tour guide apis 10 年之前
views.py 018d52f61d Update package django_xxx 8 年之前