修改了登录im的逻辑
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
import UIKit
|
||||
import DeviceKit
|
||||
import NSObject_Rx
|
||||
import NIMSDK
|
||||
@main
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
var window: UIWindow?
|
||||
@@ -18,7 +19,9 @@ var window: UIWindow?
|
||||
self.window = UIWindow.init(frame: UIScreen.main.bounds)
|
||||
self.window?.backgroundColor = UIColor.white
|
||||
self.window?.rootViewController = BaseNavigationViewController(rootViewController:AuthLaunchVC())
|
||||
loadNIMSDK()
|
||||
loginStateListener()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -34,13 +37,36 @@ var window: UIWindow?
|
||||
if let uid = LoginTokenConfig.config.getAccountInfo()?.uid {
|
||||
UserViewModel.userVM.getUserInfo(uid: uid)
|
||||
}
|
||||
if NIMSDK.shared().loginManager.isLogined() == false {
|
||||
if let uid = LoginTokenConfig.config.getAccountInfo()?.uid, let token = LoginTokenConfig.config.getAccountInfo()?.netEaseToken {
|
||||
NIMSDK.shared().loginManager.login("\(uid)", token: token) { error in
|
||||
print("aaa")
|
||||
}
|
||||
} else {
|
||||
///去登录
|
||||
self.window?.rootViewController = BaseNavigationViewController(rootViewController:AuthLaunchVC())
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
///去登录
|
||||
self.window?.rootViewController = BaseNavigationViewController(rootViewController:AuthLaunchVC())
|
||||
}
|
||||
}).disposed(by: rx.disposeBag)
|
||||
|
||||
UserViewModel.userVM.userInfo.subscribe(onNext: { result in
|
||||
if result.nick?.count ?? 0 <= 0 || result.avatar?.count ?? 0 <= 0 {
|
||||
let fillVC = AuthFillDataVC()
|
||||
fillVC.modalPresentationStyle = .fullScreen
|
||||
YMRequestX.topViewController()?.navigationController?.present(fillVC, animated: true)
|
||||
}
|
||||
}).disposed(by: rx.disposeBag)
|
||||
}
|
||||
|
||||
private func loadNIMSDK() {
|
||||
let opt = NIMSDKOption(appKey: AppKeys.nimAppid)
|
||||
opt.apnsCername = "yinmeng_anps"
|
||||
NIMSDK.shared().register(with: opt)
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
// YMNetworkAPI.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/24.
|
||||
// Created by Mang on 2024/2/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
@@ -37,7 +37,7 @@ class YMNetworkHelper: NSObject {
|
||||
|
||||
func requestSend(type:HTTPMethod,path:String,params:Dictionary<String, Any>, succeed:SessionCallSucceed?,fail:SessionCallFail?) -> Void {
|
||||
getHttpRequestHeaders()
|
||||
requestSend(type: type,host: "https://api.ymlive.fun/", path: path, params: params, encoding: URLEncoding.queryString, header: headersSet, succeed: succeed, fail: fail)
|
||||
requestSend(type: type,host: AppKeys.api, path: path, params: params, encoding: URLEncoding.queryString, header: headersSet, succeed: succeed, fail: fail)
|
||||
}
|
||||
|
||||
func requestSend(type:HTTPMethod,
|
||||
@@ -74,50 +74,50 @@ class YMNetworkHelper: NSObject {
|
||||
func analyzeThe(response1:AFDataResponse<Any>,
|
||||
succeed2:SessionCallSucceed?,
|
||||
fail3: SessionCallFail?,uuid4:String) -> Void {
|
||||
let maiUrlSss = response1.request?.url?.absoluteString ?? "unkown"
|
||||
let UrlSss = response1.request?.url?.absoluteString ?? "unkown"
|
||||
switch response1.result {
|
||||
case .success:
|
||||
let maiResponNk :Dictionary = response1.value as? Dictionary<String, Any> ?? Dictionary.init()
|
||||
let maiResultMo = maiResponNk
|
||||
if maiResultMo.keys.contains("code") {
|
||||
let maicodeNum :Int = maiResultMo["code"] as? Int ?? 0
|
||||
if maicodeNum == 200 {
|
||||
if maiResultMo.keys.contains("data") {
|
||||
let maiDDD = maiResultMo["data"] as Any
|
||||
succeed2?(maiDDD)
|
||||
let ResponNk :Dictionary = response1.value as? Dictionary<String, Any> ?? Dictionary.init()
|
||||
let ResultMo = ResponNk
|
||||
if ResultMo.keys.contains("code") {
|
||||
let codeNum :Int = ResultMo["code"] as? Int ?? 0
|
||||
if codeNum == 200 {
|
||||
if ResultMo.keys.contains("data") {
|
||||
let DDD = ResultMo["data"] as Any
|
||||
succeed2?(DDD)
|
||||
}else{
|
||||
succeed2?(Dictionary<String, Any>.init())
|
||||
}
|
||||
}else{
|
||||
if maicodeNum == 401 && maiUrlSss.contains("auth-center/sso/logout") == false {
|
||||
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "MAISessionTickValid"), object: nil)
|
||||
if codeNum == 401 && UrlSss.contains("auth-center/sso/logout") == false {
|
||||
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SessionTickValid"), object: nil)
|
||||
sessionNetMana.cancelAllRequests()
|
||||
}
|
||||
var messageIn = response1.error.debugDescription
|
||||
if maiResultMo.keys.contains("message") { messageIn = maiResultMo["message"] as? String ?? "" }
|
||||
fail3?(maicodeNum,messageIn)
|
||||
if ResultMo.keys.contains("message") { messageIn = ResultMo["message"] as? String ?? "" }
|
||||
fail3?(codeNum,messageIn)
|
||||
}
|
||||
} else if maiResultMo.keys.contains("errno") {
|
||||
let maiCodeNum :Int = maiResultMo["errno"] as? Int ?? 0
|
||||
if maiCodeNum == 0 {
|
||||
if maiResultMo.keys.contains("data") {
|
||||
let dataSc = maiResultMo["data"] as Any
|
||||
} else if ResultMo.keys.contains("errno") {
|
||||
let CodeNum :Int = ResultMo["errno"] as? Int ?? 0
|
||||
if CodeNum == 0 {
|
||||
if ResultMo.keys.contains("data") {
|
||||
let dataSc = ResultMo["data"] as Any
|
||||
succeed2?(dataSc)
|
||||
}else{
|
||||
succeed2?(Dictionary<String, Any>.init())
|
||||
}
|
||||
}else{
|
||||
var majmessageStr = response1.error.debugDescription
|
||||
if maiResultMo.keys.contains("errmsg") { majmessageStr = maiResultMo["errmsg"] as? String ?? ""}
|
||||
fail3?(maiCodeNum,majmessageStr)
|
||||
if ResultMo.keys.contains("errmsg") { majmessageStr = ResultMo["errmsg"] as? String ?? ""}
|
||||
fail3?(CodeNum,majmessageStr)
|
||||
}
|
||||
} else {
|
||||
fail3?(10000,"请求失败")
|
||||
}
|
||||
case let .failure(error):
|
||||
var maiErrorMssg = response1.error?.errorDescription ?? ""
|
||||
var maicodeNum = response1.error?.responseCode ?? 0
|
||||
fail3?(maicodeNum,maiErrorMssg)
|
||||
var ErrorMssg = response1.error?.errorDescription ?? ""
|
||||
var codeNum = response1.error?.responseCode ?? 0
|
||||
fail3?(codeNum,ErrorMssg)
|
||||
}
|
||||
}
|
||||
|
||||
|
17
yinmeng-ios/Base/Utils/AppKeys.swift
Normal file
17
yinmeng-ios/Base/Utils/AppKeys.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// AppKeys.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
enum AppKeys {
|
||||
#if DEBUG
|
||||
static let nimAppid = "5d5a833a2d0ff1304a5d8bed53d2af5b"
|
||||
static let api = "http://beta.api.ymlive.fun/"
|
||||
#else
|
||||
static let nimAppid = "5e76ec47632d86c30ce18eabfa332b6a"
|
||||
static let api = "https://api.ymlive.fun/"
|
||||
#endif
|
||||
}
|
@@ -9,5 +9,6 @@ import Foundation
|
||||
|
||||
enum H5Utils:String {
|
||||
case privacy = "modules/rule/privacy-wap.html"
|
||||
case user = "modules/rule/protocol.html"
|
||||
case logoff = "modules/logout/index.html"
|
||||
}
|
||||
|
@@ -31,6 +31,4 @@ let TabHeight = (49)
|
||||
|
||||
let DesKey = "1ea53d260ecf11e7b56e00163e046a26"
|
||||
|
||||
let API_URL = "http://beta.api.ymlive.fun"
|
||||
|
||||
let H5_URL = "http://beta.h5.ymlive.fun"
|
||||
|
161
yinmeng-ios/Extension/UIView/UIView+.swift
Normal file
161
yinmeng-ios/Extension/UIView/UIView+.swift
Normal file
@@ -0,0 +1,161 @@
|
||||
//
|
||||
// UIView+.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIView {
|
||||
/// x
|
||||
public var x : CGFloat {
|
||||
|
||||
get {
|
||||
return self.frame.origin.x
|
||||
}
|
||||
set (x) {
|
||||
var frame = self.frame
|
||||
frame.origin.x = x
|
||||
self.frame = frame
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// y
|
||||
public var y : CGFloat {
|
||||
|
||||
get {
|
||||
return self.frame.origin.y
|
||||
}
|
||||
set (y) {
|
||||
var frame = self.frame
|
||||
frame.origin.y = y
|
||||
self.frame = frame
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// maxX
|
||||
public var maxX : CGFloat {
|
||||
|
||||
get {
|
||||
return self.frame.maxX
|
||||
}
|
||||
set(maxX) {
|
||||
self.frame.origin.x = maxX - self.frame.size.width
|
||||
}
|
||||
}
|
||||
|
||||
/// maxY
|
||||
public var maxY : CGFloat {
|
||||
|
||||
get {
|
||||
return self.frame.maxY
|
||||
}
|
||||
set(maxY) {
|
||||
self.frame.origin.y = maxY - self.frame.size.height
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// width
|
||||
public var width : CGFloat {
|
||||
|
||||
get {
|
||||
return self.frame.size.width
|
||||
}
|
||||
set (width) {
|
||||
var frame = self.frame
|
||||
frame.size.width = width
|
||||
self.frame = frame
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// height
|
||||
public var height : CGFloat {
|
||||
|
||||
get {
|
||||
return self.frame.size.height
|
||||
}
|
||||
set (height) {
|
||||
var frame = self.frame
|
||||
frame.size.height = height
|
||||
self.frame = frame
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// centerX
|
||||
public var centerX : CGFloat {
|
||||
|
||||
get {
|
||||
return self.center.x
|
||||
}
|
||||
set (centerX) {
|
||||
var center = self.center
|
||||
center.x = centerX
|
||||
self.center = center
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// centerY
|
||||
public var centerY : CGFloat {
|
||||
|
||||
get {
|
||||
return self.center.y
|
||||
}
|
||||
set (centerY) {
|
||||
var center = self.center
|
||||
center.y = centerY
|
||||
self.center = center
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// size
|
||||
public var size : CGSize {
|
||||
|
||||
get {
|
||||
return self.frame.size
|
||||
}
|
||||
set (size) {
|
||||
var newSize = self.frame.size
|
||||
newSize = CGSize(width: size.width, height: size.height)
|
||||
self.frame.size = newSize
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// origin
|
||||
public var origin : CGPoint {
|
||||
|
||||
get {
|
||||
return self.frame.origin
|
||||
}
|
||||
set (origin) {
|
||||
var newOrigin = self.frame.origin
|
||||
newOrigin = CGPoint(x: origin.x, y: origin.y)
|
||||
self.frame.origin = newOrigin
|
||||
}
|
||||
}
|
||||
|
||||
/// borderWidth
|
||||
public var borderWidth: CGFloat {
|
||||
|
||||
get {
|
||||
return self.layer.borderWidth
|
||||
}
|
||||
set (borderWidth){
|
||||
self.layer.borderWidth = borderWidth
|
||||
|
||||
guard self.layer.masksToBounds else {
|
||||
return
|
||||
}
|
||||
self.layer.masksToBounds = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ class AuthFillDataVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
}
|
||||
|
||||
private func loadSubViews() {
|
||||
randomNick()
|
||||
view.addSubview(backImgView)
|
||||
view.addSubview(backBtn)
|
||||
view.addSubview(titleLb)
|
||||
@@ -144,6 +145,16 @@ class AuthFillDataVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
return button
|
||||
}()
|
||||
|
||||
fileprivate func randomNick() {
|
||||
RequestGet(path: "random/nick/get", parma: [:]) { text in
|
||||
if let text = text as? String {
|
||||
self.nickTextFiled.text = text
|
||||
}
|
||||
} fail: { code, msg in
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@objc func femaleBtnAction() {
|
||||
self.femaleBtn.isSelected = true
|
||||
self.maleBtn.isSelected = false
|
||||
@@ -157,14 +168,36 @@ class AuthFillDataVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
|
||||
|
||||
@objc func backBtnAction() {
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
AuthViewModel.authVM.logout()
|
||||
}
|
||||
|
||||
@objc func nickTextFiledDidChange(_ textField: UITextField) {
|
||||
|
||||
if let text = textField.text {
|
||||
if text.count > 15 {
|
||||
textField.text = text.substring(start: 0, 15)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@objc func confirmBtnAction() {
|
||||
if maleBtn.isSelected == true || femaleBtn.isSelected == true {
|
||||
if let nick = nickTextFiled.text, nick.count > 0 {
|
||||
let gender = self.maleBtn.isSelected ? "1" : "2"
|
||||
let params:[String: Any] = ["avatar":"https://image.ymlive.fun/default_avatar.png", "nick": nick, "gender":gender, "uid": AuthManager.userUid, "ticket":AuthManager.ticket]
|
||||
RequestPost(path: "user/v2/update", parma: params) { data in
|
||||
HUDTool.show(with: "更新成功")
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
} fail: { code, message in
|
||||
HUDTool.show(with: message)
|
||||
}
|
||||
} else {
|
||||
HUDTool.show(with: "请输入昵称")
|
||||
}
|
||||
} else {
|
||||
HUDTool.show(with: "请选择性别")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -281,7 +281,7 @@ class AuthLaunchVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
}
|
||||
|
||||
@objc func userProtocolBtnAction() {
|
||||
let web = WebViewController(url: "yinmeng/\(H5Utils.privacy.rawValue)")
|
||||
let web = WebViewController(url: "yinmeng/\(H5Utils.user.rawValue)")
|
||||
self.navigationController?.pushViewController(web, animated: true)
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,7 @@ class AuthManager: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class LoginTokenConfig: NSObject {
|
||||
public static let config = LoginTokenConfig.init()
|
||||
var tokenInfo: UserTokenObject?
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
import Foundation
|
||||
import RxSwift
|
||||
import NIMSDK
|
||||
class AuthViewModel: NSObject {
|
||||
static let authVM = AuthViewModel.init()
|
||||
let data = PublishSubject<Bool>()
|
||||
@@ -22,6 +23,24 @@ class AuthViewModel: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
func logout() {
|
||||
if NIMSDK.shared().loginManager.isLogined() {
|
||||
NIMSDK.shared().loginManager.logout()
|
||||
}
|
||||
let token = LoginTokenConfig.config.getAccountInfo()?.access_token
|
||||
LoginTokenConfig.config.removeTicketFromLoaction()
|
||||
LoginTokenConfig.config.removeTicketFromLoaction()
|
||||
if let token = token {
|
||||
let params = ["auaccess_token": token]
|
||||
RequestPost(path: "acc/logout", parma: params) { data in
|
||||
print("你好")
|
||||
} fail: { code, msg in
|
||||
print("de")
|
||||
}
|
||||
}
|
||||
self.loginSuccess.onNext(false)
|
||||
}
|
||||
|
||||
///获取验证码
|
||||
func getSmsCode(phone:String, type:Int) {
|
||||
if let phoneDes = phone.encrypt() {
|
||||
@@ -106,14 +125,11 @@ class AuthViewModel: NSObject {
|
||||
if let dic = data as? [String: Any], let tickets = dic["tickets"] as? [[String: Any]], let ticket1 = tickets[safe: 0], let ticket = ticket1["ticket"] as? String{
|
||||
LoginTokenConfig.config.saveTicketToLoaction(ticket: ticket)
|
||||
self.loginSuccess.onNext(true)
|
||||
self.loginSuccess.onCompleted()
|
||||
} else {
|
||||
self.loginSuccess.onNext(false)
|
||||
self.loginSuccess.onCompleted()
|
||||
}
|
||||
} fail: { code, message in
|
||||
self.loginSuccess.onNext(false)
|
||||
self.loginSuccess.onCompleted()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,13 +6,136 @@
|
||||
// 回话列表
|
||||
|
||||
import UIKit
|
||||
|
||||
import NIMSDK
|
||||
class ChatListVC: BaseViewController {
|
||||
|
||||
var list:NSMutableArray?
|
||||
|
||||
deinit {
|
||||
NIMSDK.shared().loginManager.remove(self)
|
||||
NIMSDK.shared().conversationManager.remove(self)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
NIMSDK.shared().conversationManager.add(self)
|
||||
NIMSDK.shared().loginManager.add(self)
|
||||
getList()
|
||||
}
|
||||
|
||||
private lazy var tableView: UITableView = {
|
||||
let tableView = UITableView(frame: .zero, style: .plain)
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = self
|
||||
tableView.tableFooterView = UIView()
|
||||
tableView.separatorStyle = .none
|
||||
tableView.backgroundColor = .clear
|
||||
if #available(iOS 11.0, *) {
|
||||
tableView.contentInsetAdjustmentBehavior = .never
|
||||
}
|
||||
tableView.register(cellType: ChatListCell.self)
|
||||
return tableView
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
extension ChatListVC: UITableViewDelegate, UITableViewDataSource {
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatListCell.self)
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return list?.count ?? 0
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
return 64
|
||||
}
|
||||
}
|
||||
|
||||
extension ChatListVC: NIMConversationManagerDelegate, NIMLoginManagerDelegate {
|
||||
func onLogin(_ step: NIMLoginStep) {
|
||||
if (step == .syncOK) {
|
||||
getList()
|
||||
}
|
||||
}
|
||||
|
||||
func didLoadAllRecentSessionCompletion() {
|
||||
getList()
|
||||
}
|
||||
|
||||
func didAdd(_ recentSession: NIMRecentSession, totalUnreadCount: Int) {
|
||||
var isInList = false
|
||||
for index in 0..<(list?.count ?? 0) {
|
||||
let recent = list?[index] as? NIMRecentSession
|
||||
if recent?.session?.sessionId == recentSession.session?.sessionId{
|
||||
isInList = true
|
||||
list?.replaceObject(at: index, with: recentSession)
|
||||
break
|
||||
}
|
||||
}
|
||||
if isInList == false {
|
||||
list?.add(recentSession)
|
||||
}
|
||||
mai_sortMessages()
|
||||
updateItemBadge()
|
||||
}
|
||||
|
||||
func didUpdate(_ recentSession: NIMRecentSession, totalUnreadCount: Int) {
|
||||
var isInList = false
|
||||
for index in 0..<(list?.count ?? 0) {
|
||||
let session = list?[index] as? NIMRecentSession
|
||||
if session?.session?.sessionId == recentSession.session?.sessionId{
|
||||
isInList = true
|
||||
list?.replaceObject(at: index, with: recentSession)
|
||||
break
|
||||
}
|
||||
}
|
||||
if isInList == false {
|
||||
list?.add(recentSession)
|
||||
}
|
||||
mai_sortMessages()
|
||||
updateItemBadge()
|
||||
}
|
||||
|
||||
func didRemove(_ recentSession: NIMRecentSession, totalUnreadCount: Int) {
|
||||
let arr = NSArray.init(object: recentSession.session as Any)
|
||||
NIMSDK.shared().conversationManager.deleteRemoteSessions(arr as! [NIMSession], completion: nil)
|
||||
tableView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
extension ChatListVC {
|
||||
|
||||
fileprivate func getList() {
|
||||
if let array = NIMSDK.shared().conversationManager.allRecentSessions() {
|
||||
list = NSMutableArray.init(array: array)
|
||||
mai_sortMessages()
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func mai_sortMessages() -> Void {
|
||||
var arr = list?.sortedArray(options: NSSortOptions.stable, usingComparator: { obj1, obj2 in
|
||||
let item1 = obj1 as? NIMRecentSession
|
||||
let item2 = obj2 as? NIMRecentSession
|
||||
let time1 = (item1?.lastMessage?.timestamp ?? 0) as Double
|
||||
let time2 = (item2?.lastMessage?.timestamp ?? 0) as Double
|
||||
if time1 < time2{
|
||||
return .orderedDescending
|
||||
}
|
||||
return .orderedAscending
|
||||
})
|
||||
|
||||
if let array = arr {
|
||||
list = NSMutableArray(array: array)
|
||||
}
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
|
||||
private func updateItemBadge() {
|
||||
let unreadCount = NIMSDK.shared().conversationManager.allUnreadCount()
|
||||
self.tabBarItem.badgeValue = "\(unreadCount)"
|
||||
}
|
||||
}
|
||||
|
@@ -9,25 +9,39 @@ import UIKit
|
||||
import NIMSDK
|
||||
class ChatVC: BaseViewController {
|
||||
|
||||
// 键盘收起/弹出 滚动的时候收起输入栏
|
||||
private var isBecome: Bool = false
|
||||
/// 是否发送完成
|
||||
private var isSended: Bool = true
|
||||
/// 输入栏默认的高度
|
||||
private let ToolBarLastH: CGFloat = 52
|
||||
|
||||
public init(session: NIMSession) {
|
||||
vm = ChatViewModel(session: session)
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
// vm.delegate = self
|
||||
// NIMSDK.shared().mediaManager.add(self)
|
||||
}
|
||||
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
var vm:ChatViewModel
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = .orange
|
||||
}
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = ThemeColor(hexStr: "#F6F6F6")
|
||||
let height = ScreenHeight - (ToolBarLastH + SafeAraeBottomHeight + NavHeight)
|
||||
chatTableView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: height)
|
||||
view.addSubview(chatTableView)
|
||||
view.addSubview(keyboardView)
|
||||
}
|
||||
|
||||
///注册cell
|
||||
private func registerChatCell() {
|
||||
chatTableView.register(cellType: ChatTextCell.self)
|
||||
}
|
||||
|
||||
private lazy var chatTableView: UITableView = {
|
||||
let tableView = UITableView(frame: .zero, style: .plain)
|
||||
@@ -42,20 +56,57 @@ class ChatVC: BaseViewController {
|
||||
return tableView
|
||||
}()
|
||||
|
||||
private lazy var keyboardView: ChatKeyboardView = {
|
||||
let toolBarY = ScreenHeight - NavHeight - ToolBarLastH - SafeAraeBottomHeight
|
||||
let view = ChatKeyboardView(frame: CGRect(x: 0, y: toolBarY, width: ScreenWidth, height: ToolBarLastH))
|
||||
view.delegate = self
|
||||
return view
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
extension ChatVC: UITableViewDelegate, UITableViewDataSource {
|
||||
// MARK: - ChatKeyboardViewDelegate
|
||||
extension ChatVC: ChatKeyboardViewDelegate {
|
||||
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String) {
|
||||
///发送消息
|
||||
vm.sendTextMessage(text: content) { error in
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool) {
|
||||
self.isSended = true
|
||||
self.isBecome = isBecome
|
||||
}
|
||||
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType) {
|
||||
|
||||
//TODO: 点击更多
|
||||
}
|
||||
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension ChatVC: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return vm.messageObjects.count
|
||||
}
|
||||
|
||||
public func tableView(_ tableView: UITableView,
|
||||
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let model = vm.messageObjects[safe: indexPath.row]
|
||||
if model?.type == .text {
|
||||
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatTextCell.self)
|
||||
cell.model = model
|
||||
}
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
|
||||
tableView.deselectRow(at: indexPath, animated: true)
|
||||
}
|
||||
|
||||
public func tableView(_ tableView: UITableView,
|
||||
@@ -63,4 +114,22 @@ extension ChatVC: UITableViewDelegate, UITableViewDataSource {
|
||||
let m = vm.messageObjects[safe:indexPath.row]
|
||||
return CGFloat(m?.height ?? 0)
|
||||
}
|
||||
|
||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||
if isSended {
|
||||
isSended = false
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if isSended {
|
||||
return
|
||||
}
|
||||
|
||||
if chatTableView.y <= 0 && isBecome {
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: .kChatTextKeyboardNeedHide, object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
153
yinmeng-ios/Modules/Chat/Keyboard/ChatGrowingTextView.swift
Normal file
153
yinmeng-ios/Modules/Chat/Keyboard/ChatGrowingTextView.swift
Normal file
@@ -0,0 +1,153 @@
|
||||
//
|
||||
// ChatGrowingTextView.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class ChatGrowingTextView: UITextView {
|
||||
/// 行数部分间距调整
|
||||
fileprivate let kEdgeInset: CGFloat = 12
|
||||
/// 内容字体默认大小
|
||||
fileprivate let kDefultSize: CGFloat = 15.0
|
||||
|
||||
// MARK: - var lazy
|
||||
|
||||
/// 默认3行的高度
|
||||
fileprivate var maxTextViewHeight: CGFloat = 80
|
||||
|
||||
var placeholder: String? = "" {
|
||||
didSet {
|
||||
self.placeholderLabel.text = placeholder
|
||||
}
|
||||
}
|
||||
|
||||
var placeholderColor: UIColor? = .black {
|
||||
didSet {
|
||||
self.placeholderLabel.textColor = placeholderColor
|
||||
}
|
||||
}
|
||||
|
||||
var maxNumberOfLines: Int = 3 {
|
||||
didSet {
|
||||
let numberOfLines = CGFloat(maxNumberOfLines)
|
||||
maxTextViewHeight = CGFloat(ceilf(Float(self.font!.lineHeight * numberOfLines + self.textContainerInset.top + self.textContainerInset.bottom))) - kEdgeInset
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// 输入框高度监听回调
|
||||
var didTextChangedHeightClosure : ((CGFloat)->Void)?
|
||||
|
||||
/// 占位标签
|
||||
fileprivate lazy var placeholderLabel: UILabel = {
|
||||
let frame = CGRect(x: 5, y: 7, width: ScreenWidth - 10, height: 21)
|
||||
let label = UILabel(frame: frame)
|
||||
label.numberOfLines = 1
|
||||
label.text = "请输入你要发送的消息"
|
||||
label.textColor = ThemeColor(hexStr: "#F6F6F6")
|
||||
label.font = UIFont.systemFont(ofSize: self.kDefultSize)
|
||||
return label
|
||||
}()
|
||||
|
||||
// MARK: - life cycle
|
||||
|
||||
override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||
super.init(frame: frame, textContainer: textContainer)
|
||||
|
||||
setup()
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
fileprivate func setup() {
|
||||
backgroundColor = .white
|
||||
|
||||
self.isScrollEnabled = false
|
||||
self.scrollsToTop = false
|
||||
//self.contentInset = UIEdgeInsets(top: 1, left: 0, bottom: 1, right: 0)
|
||||
self.showsHorizontalScrollIndicator = false
|
||||
self.enablesReturnKeyAutomatically = true
|
||||
self.font = UIFont.systemFont(ofSize: kDefultSize)
|
||||
self.returnKeyType = .send
|
||||
|
||||
self.layer.cornerRadius = 4
|
||||
self.layer.borderWidth = 1
|
||||
self.layer.borderColor = ThemeColor(hexStr: "#2C363E").cgColor
|
||||
self.layer.masksToBounds = true
|
||||
// 添加占位控件
|
||||
addSubview(self.placeholderLabel)
|
||||
|
||||
// register
|
||||
registerChangeNotification()
|
||||
}
|
||||
|
||||
fileprivate func registerChangeNotification() {
|
||||
// 实时监听输入值的改变
|
||||
NotificationCenter.default.addObserver(self,
|
||||
selector: #selector(textDidChanged),
|
||||
name: UITextView.textDidChangeNotification,
|
||||
object: self)
|
||||
|
||||
self.addObserver(self, forKeyPath: "attributedText", options: .new, context: nil)
|
||||
}
|
||||
|
||||
// MARK: - KVO监听
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if keyPath == "attributedText" {
|
||||
textDidChanged()
|
||||
}else {
|
||||
|
||||
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
self.removeObserver(self, forKeyPath: "attributedText")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Action
|
||||
|
||||
extension ChatGrowingTextView {
|
||||
|
||||
@objc func textDidChanged() {
|
||||
placeholderLabel.isHidden = self.hasText
|
||||
|
||||
// 计算高度
|
||||
let constrainSize = CGSize(width: self.frame.size.width, height: CGFloat(MAXFLOAT))
|
||||
var size = self.sizeThatFits(constrainSize)
|
||||
|
||||
if size.height >= maxTextViewHeight {
|
||||
self.isScrollEnabled = true
|
||||
size.height = maxTextViewHeight
|
||||
}else {
|
||||
self.isScrollEnabled = false
|
||||
if (didTextChangedHeightClosure != nil && !self.isScrollEnabled) {
|
||||
didTextChangedHeightClosure?(size.height)
|
||||
}
|
||||
}
|
||||
|
||||
let nowFrame = self.frame
|
||||
frame.size.height = size.height
|
||||
self.frame = nowFrame
|
||||
|
||||
self.layoutIfNeeded()
|
||||
|
||||
sendChangedNoti()
|
||||
}
|
||||
|
||||
func sendChangedNoti() {
|
||||
|
||||
NotificationCenter.default.post(name: .kChatTextKeyboardChanged, object: self.text, userInfo: nil)
|
||||
}
|
||||
}
|
29
yinmeng-ios/Modules/Chat/Keyboard/ChatKeyboard+.swift
Normal file
29
yinmeng-ios/Modules/Chat/Keyboard/ChatKeyboard+.swift
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// ChatKeyboard+.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
// MARK: - NSNotificationName
|
||||
|
||||
public extension NSNotification.Name {
|
||||
/// 获取点击空白处回收键盘的处理通知
|
||||
static let kChatTextKeyboardNeedHide = Notification.Name("kChatTextKeyboardNeedHide")
|
||||
/// 获取文本输入框值变化
|
||||
static let kChatTextKeyboardChanged = Notification.Name("kChatTextKeyboardChanged")
|
||||
}
|
||||
|
||||
protocol OptionalType {
|
||||
associatedtype Wrapped
|
||||
|
||||
var value: Wrapped? { get }
|
||||
}
|
||||
|
||||
|
||||
extension Optional: OptionalType {
|
||||
var value: Wrapped? {
|
||||
return self
|
||||
}
|
||||
}
|
371
yinmeng-ios/Modules/Chat/Keyboard/ChatKeyboardView.swift
Normal file
371
yinmeng-ios/Modules/Chat/Keyboard/ChatKeyboardView.swift
Normal file
@@ -0,0 +1,371 @@
|
||||
//
|
||||
// ChatKeyboardView.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol ChatKeyboardViewDelegate: NSObjectProtocol {
|
||||
/// 输入完消息
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String)
|
||||
/// 键盘收起/弹出
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool)
|
||||
/// 键盘的y值
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat)
|
||||
/// 菜单栏点击
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType)
|
||||
}
|
||||
|
||||
extension ChatKeyboardViewDelegate {
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String) {}
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool) {}
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat) {}
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType) {}
|
||||
}
|
||||
|
||||
|
||||
class ChatKeyboardView: UIView {
|
||||
|
||||
private let kSpace: CGFloat = 8.0
|
||||
private let kViewWH: CGFloat = 36.0
|
||||
private let kLineHeight: CGFloat = 0.75
|
||||
|
||||
// MARK: - var lazy
|
||||
|
||||
weak var delegate: ChatKeyboardViewDelegate?
|
||||
|
||||
fileprivate var toolBarHeight: CGFloat = 52.0
|
||||
fileprivate var lastTextHeight: CGFloat = 34.0
|
||||
fileprivate var keyboardHeight: CGFloat = 0.0
|
||||
|
||||
/// 底部菜单容器高度
|
||||
fileprivate var contentHeight: CGFloat = 0.0
|
||||
fileprivate var isShowMore = false
|
||||
|
||||
/// 是否弹出了系统键盘
|
||||
fileprivate var isShowKeyboard = false
|
||||
|
||||
/// 更多按钮
|
||||
fileprivate lazy var moreButton : UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
let x: CGFloat = ScreenWidth - self.kViewWH - self.kSpace
|
||||
button.frame = CGRect(x: x, y: self.kSpace, width: self.kViewWH, height: self.kViewWH)
|
||||
button.setImage(UIImage(named: "chat_more"), for: .normal)
|
||||
button.setImage(UIImage(named: "chat_more"), for: .highlighted)
|
||||
button.addTarget(self, action: #selector(moreDidAction(_:)), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
/// 文本输入框
|
||||
fileprivate lazy var chatTextView: ChatGrowingTextView = {
|
||||
let w: CGFloat = ScreenWidth - self.kViewWH * 2 - self.kSpace * 3 - self.kSpace
|
||||
let textView = ChatGrowingTextView(frame: CGRect(x: self.kSpace, y: self.kSpace, width: w, height: self.kViewWH))
|
||||
textView.placeholder = "请输入..."
|
||||
textView.textColor = ThemeColor(hexStr: "#000000")
|
||||
textView.maxNumberOfLines = 5
|
||||
textView.delegate = self
|
||||
textView.didTextChangedHeightClosure = { [weak self] height in
|
||||
self?.changeKeyboardHeight(height: height)
|
||||
}
|
||||
return textView
|
||||
}()
|
||||
|
||||
fileprivate lazy var topLineView: UIView = {
|
||||
let lineView1 = UIView(frame: CGRect(x: 0, y: 0, width: ScreenWidth, height: kLineHeight))
|
||||
lineView1.backgroundColor = ThemeColor(hexStr: "#E5E5E5")
|
||||
return lineView1
|
||||
}()
|
||||
|
||||
fileprivate lazy var bottomLineView: UIView = {
|
||||
let lineView2 = UIView(frame: CGRect(x: 0, y: self.toolBarHeight - kLineHeight, width: ScreenWidth, height: kLineHeight))
|
||||
lineView2.backgroundColor = ThemeColor(hexStr: "#E5E5E5")
|
||||
return lineView2
|
||||
}()
|
||||
|
||||
fileprivate lazy var toolBarView: UIView = {
|
||||
let view = UIView(frame: CGRect(x: 0, y: 0, width: ScreenWidth, height: self.toolBarHeight))
|
||||
view.backgroundColor = ThemeColor(hexStr: "#F7F7F7")
|
||||
return view
|
||||
}()
|
||||
|
||||
/// 底部背景容器
|
||||
fileprivate lazy var contentView: UIView = {
|
||||
let y = self.toolBarView.maxY
|
||||
let view = UIView(frame: CGRect(x: 0, y: y, width: ScreenWidth, height: self.contentHeight))
|
||||
view.backgroundColor = ThemeColor(hexStr: "#F8F8F8")
|
||||
return view
|
||||
}()
|
||||
|
||||
/// 更多菜单
|
||||
fileprivate lazy var moreMenuView: ChatMoreMenuView = {
|
||||
let view = ChatMoreMenuView(frame: self.contentView.bounds)
|
||||
view.isHidden = true
|
||||
view.delegate = self
|
||||
return view
|
||||
}()
|
||||
|
||||
// MARK: - life cycle
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
setupKeyboardView()
|
||||
registerNotification()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
setupKeyboardView()
|
||||
registerNotification()
|
||||
}
|
||||
|
||||
func setupKeyboardView() {
|
||||
self.backgroundColor = ThemeColor(hexStr: "#F7F7F7")
|
||||
self.isUserInteractionEnabled = true
|
||||
|
||||
addSubview(toolBarView)
|
||||
toolBarView.addSubview(moreButton)
|
||||
toolBarView.addSubview(chatTextView)
|
||||
toolBarView.addSubview(topLineView)
|
||||
toolBarView.addSubview(bottomLineView)
|
||||
|
||||
addSubview(contentView)
|
||||
contentView.addSubview(moreMenuView)
|
||||
}
|
||||
|
||||
// MARK: - 监听键盘通知
|
||||
private func registerNotification() {
|
||||
// 监听键盘弹出通知
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)),
|
||||
name:UIResponder.keyboardWillShowNotification,object: nil)
|
||||
// 监听键盘隐藏通知
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(keyboardWillHide(_:)),
|
||||
name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
|
||||
// 主要是为了获取点击空白处回收键盘的处理
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(keyboardNeedHide),
|
||||
name: .kChatTextKeyboardNeedHide, object: nil)
|
||||
// 添加KVO监听输入键盘y值
|
||||
addObserver(self, forKeyPath: "frame", options: [.new, .old], context: nil)
|
||||
}
|
||||
|
||||
// MARK: - KVO监听
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if keyPath == "frame" && ((object as? UIView) != nil) {
|
||||
if let changeObject = change.value {
|
||||
if let newFrame = changeObject[.newKey] as? CGRect {
|
||||
delegate?.keyboard(self, DidObserver: newFrame.origin.y)
|
||||
print("y值发生改变\(newFrame.origin.y)")
|
||||
}
|
||||
}
|
||||
}else {
|
||||
|
||||
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
self.removeObserver(self, forKeyPath: "frame")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ChatMoreMenuViewDelegate
|
||||
|
||||
extension ChatKeyboardView: ChatMoreMenuViewDelegate {
|
||||
|
||||
func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType) {
|
||||
|
||||
delegate?.keyboard(self, DidMoreMenu: type)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UITextViewDelegate
|
||||
|
||||
extension ChatKeyboardView: UITextViewDelegate {
|
||||
|
||||
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
|
||||
// 发送键&回车键处理
|
||||
if (text == "\n") {
|
||||
if (isShowKeyboard) {
|
||||
isShowKeyboard = true
|
||||
}
|
||||
|
||||
sendChatMessage()
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
/// 发送消息内容
|
||||
private func sendChatMessage() {
|
||||
delegate?.keyboard(self, DidFinish: self.chatTextView.text ?? "")
|
||||
|
||||
changeKeyboardHeight(height: lastTextHeight)
|
||||
chatTextView.text = ""
|
||||
chatTextView.attributedText = NSAttributedString(string: "")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyBoard Manager
|
||||
|
||||
extension ChatKeyboardView {
|
||||
|
||||
/// 键盘将要显示
|
||||
@objc func keyboardWillShow(_ noti: NSNotification) {
|
||||
guard let userInfo = noti.userInfo else {
|
||||
return
|
||||
}
|
||||
|
||||
contentHeight = 0
|
||||
delegate?.keyboard(self, DidBecome: true)
|
||||
|
||||
let duration = userInfo["UIKeyboardAnimationDurationUserInfoKey"] as! Double
|
||||
let endFrame = (userInfo["UIKeyboardFrameEndUserInfoKey"] as! NSValue).cgRectValue
|
||||
let y = endFrame.origin.y
|
||||
// 获取键盘的高度
|
||||
keyboardHeight = endFrame.height
|
||||
// 键盘弹出状态
|
||||
isShowKeyboard = true
|
||||
|
||||
let option = userInfo["UIKeyboardAnimationCurveUserInfoKey"] as! Int
|
||||
|
||||
var changedY = y - self.toolBarHeight - NavHeight - contentHeight
|
||||
if (isShowMore) { //显示系统键盘
|
||||
isShowMore = false
|
||||
self.moreMenuView.isHidden = true
|
||||
self.moreMenuView.hidePageController = true
|
||||
changedY = y - self.toolBarHeight - NavHeight
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: UIView.AnimationOptions.RawValue(option)), animations: {
|
||||
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: self.toolBarHeight + self.contentHeight)
|
||||
}, completion: nil)
|
||||
}
|
||||
|
||||
/// 键盘将要消失
|
||||
@objc func keyboardWillHide(_ noti: NSNotification) {
|
||||
guard let userInfo = noti.userInfo else {
|
||||
return
|
||||
}
|
||||
|
||||
delegate?.keyboard(self, DidBecome: false)
|
||||
|
||||
let duration = userInfo["UIKeyboardAnimationDurationUserInfoKey"] as! Double
|
||||
let endFrame = (userInfo["UIKeyboardFrameEndUserInfoKey"] as! NSValue).cgRectValue
|
||||
//let y = endFrame.origin.y
|
||||
// 获取键盘的高度
|
||||
keyboardHeight = endFrame.height
|
||||
// 键盘弹出状态
|
||||
isShowKeyboard = false
|
||||
|
||||
let option = userInfo["UIKeyboardAnimationCurveUserInfoKey"] as! Int
|
||||
let changedY = ScreenHeight - NavHeight - self.toolBarHeight - SafeAraeBottomHeight - self.contentHeight
|
||||
UIView.animate(withDuration: duration, delay: 0, options: UIView.AnimationOptions(rawValue: UIView.AnimationOptions.RawValue(option)), animations: {
|
||||
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: self.toolBarHeight + self.contentHeight)
|
||||
}, completion: nil)
|
||||
}
|
||||
|
||||
@objc func keyboardNeedHide(_ noti: NSNotification) {
|
||||
|
||||
chatTextView.resignFirstResponder()
|
||||
moreMenuView.hidePageController = true
|
||||
|
||||
contentHeight = 0.0
|
||||
restToolbarContentHeight(true)
|
||||
|
||||
delegate?.keyboard(self, DidBecome: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: - Action
|
||||
|
||||
extension ChatKeyboardView {
|
||||
/// 更多按钮点击处理
|
||||
@objc func moreDidAction(_ button: UIButton) {
|
||||
// 如有弹出菜单
|
||||
if isShowMore {
|
||||
return
|
||||
}
|
||||
|
||||
isShowMore = true
|
||||
contentHeight = 250
|
||||
contentView.isHidden = false
|
||||
moreMenuView.isHidden = false
|
||||
chatTextView.resignFirstResponder()
|
||||
|
||||
restToolbarContentHeight()
|
||||
moreMenuView.reloadData()
|
||||
|
||||
delegate?.keyboard(self, DidBecome: true)
|
||||
}
|
||||
|
||||
/// 更改容器高度
|
||||
func restToolbarContentHeight(_ isRest: Bool = false) {
|
||||
var changedY = ScreenHeight - self.toolBarHeight - NavHeight - contentHeight
|
||||
if (isRest) {
|
||||
if (isShowMore) {
|
||||
isShowMore = false
|
||||
}
|
||||
|
||||
changedY = ScreenHeight - self.toolBarHeight - NavHeight - contentHeight - SafeAraeBottomHeight
|
||||
}
|
||||
|
||||
UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: {
|
||||
self.contentView.frame = CGRect(x: 0, y: self.toolBarView.maxY, width: ScreenWidth, height: self.contentHeight)
|
||||
self.moreMenuView.frame = self.contentView.bounds
|
||||
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: self.toolBarHeight + self.contentHeight)
|
||||
}, completion: nil)
|
||||
|
||||
self.layoutIfNeeded()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - 改变输入框高度位置
|
||||
|
||||
extension ChatKeyboardView {
|
||||
|
||||
func changeKeyboardHeight(_ isClear: Bool = false, height: CGFloat) {
|
||||
let textHeight = height
|
||||
|
||||
toolBarHeight = textHeight + kSpace * 2
|
||||
toolBarView.frame = CGRect(x: toolBarView.x, y: 0, width: toolBarView.width, height: toolBarHeight)
|
||||
|
||||
let spaceY = toolBarView.height - kSpace - kViewWH
|
||||
chatTextView.frame = CGRect(x: chatTextView.x, y: chatTextView.x, width: chatTextView.width, height: textHeight)
|
||||
moreButton.frame = CGRect(x: moreButton.x, y: spaceY, width: moreButton.width, height: moreButton.height)
|
||||
contentView.frame = CGRect(x: contentView.x, y: toolBarView.maxY, width: contentView.width, height: contentHeight)
|
||||
|
||||
topLineView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: kLineHeight)
|
||||
bottomLineView.frame = CGRect(x: 0, y: toolBarView.height - kLineHeight, width: ScreenWidth, height: kLineHeight)
|
||||
|
||||
|
||||
if (isShowKeyboard) {
|
||||
if (isShowMore) {
|
||||
isShowMore = false
|
||||
}
|
||||
|
||||
let changedY = ScreenHeight - keyboardHeight - toolBarHeight - NavHeight
|
||||
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: toolBarView.height + contentView.height)
|
||||
}else {
|
||||
let changedY = ScreenHeight - NavHeight - (toolBarView.height + contentView.height)
|
||||
self.frame = CGRect(x: 0, y: changedY, width: ScreenWidth, height: toolBarView.height + contentView.height)
|
||||
}
|
||||
|
||||
self.setNeedsLayout()
|
||||
print("self y === \(self.frame.origin.y)")
|
||||
}
|
||||
}
|
||||
|
||||
|
67
yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMenuCell.swift
Normal file
67
yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMenuCell.swift
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// ChatMoreMenuCell.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Reusable
|
||||
class ChatMoreMenuCell: UICollectionViewCell, Reusable {
|
||||
|
||||
// MARK: - lazy var
|
||||
|
||||
var model: ChatMoreMnueConfig? {
|
||||
didSet {
|
||||
guard model != nil else {
|
||||
return
|
||||
}
|
||||
|
||||
self.imageView.image = UIImage(named: model!.image!)
|
||||
self.titleLabel.text = model?.title ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textAlignment = .center
|
||||
label.textColor = .white
|
||||
label.font = UIFont.systemFont(ofSize: 14)
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var imageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
return imageView
|
||||
}()
|
||||
|
||||
// MARK: - life cycle
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
contentView.addSubview(imageView)
|
||||
contentView.addSubview(titleLabel)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
imageView.snp.makeConstraints { (make) in
|
||||
make.centerX.equalToSuperview()
|
||||
make.centerY.equalToSuperview().offset(-10)
|
||||
make.width.height.equalTo(36)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { (make) in
|
||||
make.left.right.equalToSuperview()
|
||||
make.top.equalTo(imageView.snp.bottom)
|
||||
make.height.equalTo(21)
|
||||
}
|
||||
}
|
||||
}
|
262
yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMenuView.swift
Normal file
262
yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMenuView.swift
Normal file
@@ -0,0 +1,262 @@
|
||||
//
|
||||
// ChatMoreMenuView.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum ChatMoreMenuType: Int {
|
||||
case album = 1001
|
||||
case camera = 1002
|
||||
}
|
||||
|
||||
/// 行数
|
||||
fileprivate let kRowNumber = 2
|
||||
/// 列数
|
||||
fileprivate let kColumnNumber = 4
|
||||
|
||||
fileprivate let kMoreMenuCellNumberOfOnePage = kRowNumber * kColumnNumber
|
||||
|
||||
protocol ChatMoreMenuViewDelegate {
|
||||
/// 获取选择的菜单
|
||||
func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType)
|
||||
}
|
||||
|
||||
extension ChatMoreMenuViewDelegate {
|
||||
|
||||
func menu(_ view: ChatMoreMenuView, DidSelected type: ChatMoreMenuType) {}
|
||||
}
|
||||
|
||||
class ChatMoreMenuView: UIView {
|
||||
|
||||
// MARK: - lazy var
|
||||
|
||||
var delegate: ChatMoreMenuViewDelegate?
|
||||
|
||||
/// 隐藏分页指示器
|
||||
var hidePageController: Bool = false {
|
||||
didSet {
|
||||
self.pageControl.alpha = self.hidePageController ? 0.0 : 1.0
|
||||
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: {
|
||||
self.pageControl.isHidden = self.hidePageController
|
||||
}, completion: nil)
|
||||
|
||||
self.collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .centeredHorizontally, animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
var pageIndicatorTintColor: UIColor? {
|
||||
didSet {
|
||||
guard pageIndicatorTintColor != nil else {
|
||||
return
|
||||
}
|
||||
pageControl.pageIndicatorTintColor = pageIndicatorTintColor
|
||||
}
|
||||
}
|
||||
|
||||
var currentPageIndicatorTintColor: UIColor? {
|
||||
didSet {
|
||||
guard currentPageIndicatorTintColor != nil else {
|
||||
return
|
||||
}
|
||||
pageControl.currentPageIndicatorTintColor = currentPageIndicatorTintColor
|
||||
}
|
||||
}
|
||||
|
||||
lazy var dataSource: [ChatMoreMnueConfig] = {
|
||||
let configs = [
|
||||
ChatMoreMnueConfig(title: "图片", image: "ic_more_album", type: .album),
|
||||
ChatMoreMnueConfig(title: "拍照", image: "ic_more_camera", type: .camera)
|
||||
]
|
||||
return configs
|
||||
}()
|
||||
|
||||
lazy var collectionView: UICollectionView = {
|
||||
let layout = ChatKeyboardFlowLayout(column: kColumnNumber, row: kRowNumber)
|
||||
// collectionView
|
||||
let collection = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
|
||||
collection.backgroundColor = ThemeColor(hexStr: "#F8F8F8")
|
||||
collection.register(cellType: ChatMoreMenuCell.self)
|
||||
collection.showsHorizontalScrollIndicator = true
|
||||
collection.showsVerticalScrollIndicator = true
|
||||
collection.dataSource = self
|
||||
collection.delegate = self
|
||||
collection.isPagingEnabled = true
|
||||
return collection
|
||||
}()
|
||||
|
||||
lazy var pageControl: UIPageControl = {
|
||||
let pager = UIPageControl()
|
||||
pager.backgroundColor = .clear
|
||||
pager.pageIndicatorTintColor = .white
|
||||
pager.currentPageIndicatorTintColor = ThemeColor(hexStr: "#000000")
|
||||
pager.currentPage = 0
|
||||
pager.isHidden = true
|
||||
pager.numberOfPages = self.dataSource.count / kMoreMenuCellNumberOfOnePage + (self.dataSource.count % kMoreMenuCellNumberOfOnePage == 0 ? 0 : 1)
|
||||
return pager
|
||||
}()
|
||||
|
||||
// MARK: - life cycle
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
makeUI()
|
||||
reloadData()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
makeUI()
|
||||
reloadData()
|
||||
}
|
||||
|
||||
func makeUI() {
|
||||
self.backgroundColor = ThemeColor(hexStr: "#F8F8F8")
|
||||
|
||||
addSubview(pageControl)
|
||||
addSubview(collectionView)
|
||||
|
||||
pageControl.snp.makeConstraints { make in
|
||||
make.bottom.equalToSuperview().offset(-SafeAraeBottomHeight)
|
||||
make.centerX.equalToSuperview()
|
||||
make.height.equalTo(30)
|
||||
}
|
||||
|
||||
collectionView.snp.makeConstraints { make in
|
||||
make.top.left.right.equalToSuperview()
|
||||
make.bottom.equalTo(pageControl.snp.top)
|
||||
}
|
||||
}
|
||||
|
||||
open func reloadData() {
|
||||
self.needsUpdateConstraints()
|
||||
self.layoutIfNeeded()
|
||||
|
||||
UIView.animate(withDuration: 0.15, delay: 0, options: .curveEaseOut, animations: {
|
||||
self.pageControl.alpha = 1.0
|
||||
self.pageControl.isHidden = false
|
||||
}, completion: nil)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UICollectionViewDataSource
|
||||
|
||||
extension ChatMoreMenuView: UICollectionViewDataSource {
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return dataSource.count
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
let cell = collectionView.dequeueReusableCell(for: indexPath, cellType: ChatMoreMenuCell.self)
|
||||
if let model = dataSource[safe: indexPath.row] {
|
||||
cell.model = model
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UICollectionViewDelegate
|
||||
|
||||
extension ChatMoreMenuView: UICollectionViewDelegate {
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
if let model = dataSource[safe: indexPath.row] {
|
||||
delegate?.menu(self, DidSelected: model.type!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ChatMoreMenuView {
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if scrollView == collectionView {
|
||||
let offsetX = scrollView.contentOffset.x
|
||||
let index = offsetX / ScreenWidth
|
||||
pageControl.currentPage = Int(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChatKeyboardFlowLayout: UICollectionViewFlowLayout {
|
||||
// 保存所有item
|
||||
fileprivate var attributesArr: [UICollectionViewLayoutAttributes] = []
|
||||
fileprivate var col: Int = 0
|
||||
fileprivate var row: Int = 0
|
||||
|
||||
init(column: Int, row: Int) {
|
||||
super.init()
|
||||
self.col = column
|
||||
self.row = row
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
// MARK: - 重新布局
|
||||
override func prepare() {
|
||||
super.prepare()
|
||||
|
||||
let itemWH: CGFloat = ScreenWidth / CGFloat(col)
|
||||
|
||||
// 设置itemSize
|
||||
itemSize = CGSize(width: itemWH, height: itemWH)
|
||||
minimumLineSpacing = 0
|
||||
minimumInteritemSpacing = 0
|
||||
scrollDirection = .horizontal
|
||||
|
||||
// 设置collectionView属性
|
||||
collectionView?.isPagingEnabled = true
|
||||
collectionView?.showsHorizontalScrollIndicator = false
|
||||
collectionView?.showsVerticalScrollIndicator = true
|
||||
let insertMargin = (collectionView!.bounds.height - CGFloat(row) * itemWH) * 0.5
|
||||
collectionView?.contentInset = UIEdgeInsets(top: insertMargin, left: 0, bottom: insertMargin, right: 0)
|
||||
|
||||
var page = 0
|
||||
let itemsCount = collectionView?.numberOfItems(inSection: 0) ?? 0
|
||||
for itemIndex in 0..<itemsCount {
|
||||
let indexPath = IndexPath(item: itemIndex, section: 0)
|
||||
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
|
||||
|
||||
page = itemIndex / (col * row)
|
||||
// 通过一系列计算, 得到x, y值
|
||||
let x = itemSize.width * CGFloat(itemIndex % Int(col)) + (CGFloat(page) * ScreenWidth)
|
||||
let y = itemSize.height * CGFloat((itemIndex - page * row * col) / col)
|
||||
|
||||
attributes.frame = CGRect(x: x, y: y, width: itemSize.width, height: itemSize.height)
|
||||
// 把每一个新的属性保存起来
|
||||
attributesArr.append(attributes)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||
var rectAttributes: [UICollectionViewLayoutAttributes] = []
|
||||
_ = attributesArr.map({
|
||||
if rect.contains($0.frame) {
|
||||
rectAttributes.append($0)
|
||||
}
|
||||
})
|
||||
return rectAttributes
|
||||
}
|
||||
|
||||
override var collectionViewContentSize: CGSize {
|
||||
let size: CGSize = super.collectionViewContentSize
|
||||
let collectionViewWidth: CGFloat = self.collectionView!.frame.size.width
|
||||
let nbOfScreen: Int = Int(ceil(size.width / collectionViewWidth))
|
||||
let newSize: CGSize = CGSize(width: collectionViewWidth * CGFloat(nbOfScreen), height: size.height)
|
||||
return newSize
|
||||
}
|
||||
}
|
||||
|
25
yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMnueConfig.swift
Normal file
25
yinmeng-ios/Modules/Chat/Keyboard/ChatMoreMnueConfig.swift
Normal file
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// ChatMoreMnueConfig.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ChatMoreMnueConfig: NSObject {
|
||||
var title: String?
|
||||
var image: String?
|
||||
|
||||
var type: ChatMoreMenuType?
|
||||
|
||||
init(title: String, image: String, type: ChatMoreMenuType) {
|
||||
super.init()
|
||||
|
||||
self.title = title
|
||||
self.image = image
|
||||
self.type = type
|
||||
}
|
||||
|
||||
required override init() { }
|
||||
}
|
@@ -13,7 +13,7 @@ protocol ChatBaseCellProtocol: NSObjectProtocol {
|
||||
|
||||
class ChatBaseCell: UITableViewCell, Reusable{
|
||||
weak var delegate: ChatBaseCellProtocol?
|
||||
var model:ChatBaseObject? {
|
||||
var model:ChatSessionProtocol? {
|
||||
didSet {
|
||||
guard let _ = model else {return}
|
||||
layoutMessageCell()
|
||||
|
71
yinmeng-ios/Modules/Chat/View/ChatList/ChatListCell.swift
Normal file
71
yinmeng-ios/Modules/Chat/View/ChatList/ChatListCell.swift
Normal file
@@ -0,0 +1,71 @@
|
||||
//
|
||||
// ChatListCell.swift
|
||||
// yinmeng-ios
|
||||
//
|
||||
// Created by MaiMang on 2024/2/29.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Reusable
|
||||
class ChatListCell: UITableViewCell, Reusable {
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
contentView.addSubview(backView)
|
||||
backView.addSubview(avatarImgView)
|
||||
backView.addSubview(textLb)
|
||||
backView.addSubview(nameLb)
|
||||
backView.addSubview(dateLb)
|
||||
}
|
||||
|
||||
private lazy var backView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = ThemeColor(hexStr: "#525566")
|
||||
view.layer.masksToBounds = true
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var avatarImgView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
imageView.isUserInteractionEnabled = true
|
||||
imageView.layer.masksToBounds = true
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
imageView.layer.cornerRadius = 30
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var textLb: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = UIColor(white: 1, alpha: 0.8)
|
||||
label.font = UIFont.systemFont(ofSize: 14)
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var nameLb: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = .white
|
||||
label.font = UIFont.systemFont(ofSize: 15, weight: .medium)
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var dateLb: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = .red
|
||||
label.font = UIFont.systemFont(ofSize: 12, weight: .light)
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var badgeLb: UILabel = {
|
||||
let label = UILabel()
|
||||
label.textColor = .white
|
||||
label.backgroundColor = .red
|
||||
label.textAlignment = .center
|
||||
label.font = UIFont.systemFont(ofSize: 11)
|
||||
return label
|
||||
}()
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
@@ -85,8 +85,6 @@ class PlanetStarVC: BaseViewController,HiddenNavigationBarProtocol {
|
||||
self?.navigationController?.pushViewController(chatVC, animated: true)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
var giftModel:PlanetStarModel?
|
||||
|
@@ -62,7 +62,6 @@ make.size.equalTo(CGSize(width: 14, height: 14))
|
||||
}
|
||||
|
||||
@objc func privacyRecognizer() {
|
||||
//TODO: 跳转隐私政策的
|
||||
let web = WebViewController(url: "yinmeng/\(H5Utils.privacy.rawValue)")
|
||||
self.navigationController?.pushViewController(web, animated: true)
|
||||
}
|
||||
|
@@ -71,7 +71,7 @@ class UserInfoVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
}
|
||||
|
||||
@objc func logoutBtnAction() {
|
||||
//TODO: 退出登录
|
||||
AuthViewModel.authVM.logout()
|
||||
}
|
||||
|
||||
private lazy var backImgView: UIImageView = {
|
||||
@@ -135,7 +135,7 @@ class UserInfoVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
|
||||
private lazy var logoutBtn: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setBackgroundImage(UIImage.gradient([ThemeColor(hexStr: "#FFC926"), ThemeColor(hexStr: "#FFE784")], radius: 0), for: .normal)
|
||||
button.setBackgroundImage(UIImage.gradient([ThemeColor(hexStr: "#FF60FD"), ThemeColor(hexStr: "#8974FF"), ThemeColor(hexStr: "#69EBFF")], radius: 0), for: .normal)
|
||||
button.setTitle("退出登录", for: .normal)
|
||||
button.setTitleColor(UIColor.white, for: .normal)
|
||||
button.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
|
||||
|
@@ -6,18 +6,19 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
import RxSwift
|
||||
class UserViewModel: NSObject {
|
||||
static let userVM = UserViewModel.init()
|
||||
|
||||
let userInfo = PublishSubject<UserObject>()
|
||||
func getUserInfo(uid:Int) {
|
||||
let params = ["uid":uid]
|
||||
RequestGet(path: "user/get", parma: params) { data in
|
||||
if let info = Deserialized<UserObject>.toModel(with: data) {
|
||||
print("用户信息是")
|
||||
if var info = Deserialized<UserObject>.toModel(with: data) {
|
||||
self.userInfo.onNext(info)
|
||||
}
|
||||
} fail: { code, message in
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user