Skip to content

Commit

Permalink
Merge branch 'v0.8.0' into enhancement/media-messages
Browse files Browse the repository at this point in the history
  • Loading branch information
SD10 authored Sep 20, 2017
2 parents 4670da2 + 847338c commit 603a938
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 83 deletions.
21 changes: 21 additions & 0 deletions Example/Sources/Assets.xcassets/ic_keyboard.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "icons8-keyboard.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions Example/Sources/Assets.xcassets/ic_up.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "icons8-up_arrow.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
123 changes: 93 additions & 30 deletions Example/Sources/ConversationViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,74 +39,137 @@ class ConversationViewController: MessagesViewController {
messagesCollectionView.messageCellDelegate = self
messageInputBar.delegate = self

//setupInputBar()
navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "ic_keyboard"),
style: .plain,
target: self,
action: #selector(handleKeyboardButton))
}

func setupInputBar() {
// Makes buttons with various 'hooks'
func handleKeyboardButton() {

let actionSheetController = UIAlertController(title: "Change Keyboard Style", message: nil, preferredStyle: .actionSheet)
let actions = [
UIAlertAction(title: "Slack", style: .default, handler: { _ in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: {
self.slack()
})
}),
UIAlertAction(title: "iMessage", style: .default, handler: { action in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: {
self.iMessage()
})
}),
UIAlertAction(title: "Default", style: .default, handler: { _ in
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1, execute: {
self.defaultStyle()
})
}),
UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
]
actions.forEach { actionSheetController.addAction($0) }
present(actionSheetController, animated: true, completion: nil)
}

// MARK: - Keyboard Style

func slack() {
defaultStyle()
messageInputBar.isTranslucent = false
messageInputBar.inputTextView.backgroundColor = .clear
messageInputBar.inputTextView.layer.borderWidth = 0
let items = [
makeButton(named: "ic_camera").onTextViewDidChange { button, textView in
button.isEnabled = textView.text.isEmpty
},
makeButton(named: "ic_at").onSelected { _ in
print("@ Selected")
},
makeButton(named: "ic_hashtag").onSelected { _ in
print("# Selected")
},
.flexibleSpace,
makeButton(named: "ic_library").onTextViewDidChange { button, textView in
button.isEnabled = textView.text.isEmpty
},
makeButton(named: "ic_at"),
makeButton(named: "ic_hashtag"),
.flexibleSpace,
messageInputBar.sendButton
.configure {
$0.layer.cornerRadius = 8
$0.layer.borderWidth = 1.5
$0.layer.borderColor = $0.titleColor(for: .disabled)?.cgColor
$0.setTitleColor(UIColor(colorLiteralRed: 15/255, green: 135/255, blue: 255/255, alpha: 1.0), for: .normal)
$0.setTitleColor(.white, for: .normal)
$0.setTitleColor(.white, for: .highlighted)
$0.setSize(CGSize(width: 52, height: 30), animated: false)
$0.setSize(CGSize(width: 52, height: 30), animated: true)
}.onDisabled {
$0.layer.borderColor = $0.titleColor(for: .disabled)?.cgColor
$0.backgroundColor = .white
}.onEnabled {
$0.layer.borderColor = UIColor(colorLiteralRed: 15/255, green: 135/255, blue: 255/255, alpha: 1.0).cgColor
}.onSelected {
$0.backgroundColor = UIColor(colorLiteralRed: 15/255, green: 135/255, blue: 255/255, alpha: 1.0)
$0.layer.borderColor = UIColor.clear.cgColor
}.onSelected {
// We use a transform becuase changing the size would cause the other views to relayout
$0.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
}.onDeselected {
$0.backgroundColor = .white
$0.transform = CGAffineTransform.identity
}
]
items.forEach { $0.tintColor = .lightGray }

//We can change the container insets if we want
// We can change the container insets if we want
messageInputBar.inputTextView.textContainerInset = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
messageInputBar.inputTextView.placeholderLabelInsets = UIEdgeInsets(top: 8, left: 5, bottom: 8, right: 5)

// Adjust the padding
messageInputBar.padding.top = 8
messageInputBar.padding.bottom = 8
messageInputBar.textViewPadding.bottom = 8


// Since we moved the send button to the bottom stack lets set the right stack width to 0
messageInputBar.setRightStackViewWidthContant(to: 0, animated: false)
messageInputBar.setRightStackViewWidthConstant(to: 0, animated: true)

// Finally set the items
messageInputBar.setStackViewItems(items, forStack: .bottom, animated: false)
messageInputBar.setStackViewItems(items, forStack: .bottom, animated: true)
}

func iMessage() {
defaultStyle()
messageInputBar.isTranslucent = false
messageInputBar.separatorLine.isHidden = true
messageInputBar.inputTextView.backgroundColor = UIColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1)
messageInputBar.inputTextView.placeholderTextColor = UIColor(red: 0.6, green: 0.6, blue: 0.6, alpha: 1)
messageInputBar.inputTextView.textContainerInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 36)
messageInputBar.inputTextView.placeholderLabelInsets = UIEdgeInsets(top: 8, left: 20, bottom: 8, right: 36)
messageInputBar.inputTextView.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 200/255, alpha: 1).cgColor
messageInputBar.inputTextView.layer.borderWidth = 1.0
messageInputBar.inputTextView.layer.cornerRadius = 16.0
messageInputBar.inputTextView.layer.masksToBounds = true
messageInputBar.inputTextView.scrollIndicatorInsets = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
messageInputBar.setRightStackViewWidthConstant(to: 36, animated: true)
messageInputBar.setStackViewItems([messageInputBar.sendButton], forStack: .right, animated: true)
messageInputBar.sendButton.imageView?.backgroundColor = UIColor(colorLiteralRed: 15/255, green: 135/255, blue: 255/255, alpha: 1.0)
messageInputBar.sendButton.contentEdgeInsets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
messageInputBar.sendButton.setSize(CGSize(width: 36, height: 36), animated: true)
messageInputBar.sendButton.image = #imageLiteral(resourceName: "ic_up")
messageInputBar.sendButton.title = nil
messageInputBar.sendButton.imageView?.layer.cornerRadius = 16
messageInputBar.sendButton.backgroundColor = .clear
messageInputBar.textViewPadding.right = -38
}

func defaultStyle() {
messageInputBar.inputTextView.resignFirstResponder()
let newMessageInputBar = MessageInputBar()
newMessageInputBar.delegate = self
messageInputBar = newMessageInputBar
reloadInputViews()
}

// MARK: - Helpers

func makeButton(named: String) -> InputBarButtonItem {
return InputBarButtonItem()
.configure {
$0.spacing = .fixed(10)
$0.image = UIImage(named: named)?.withRenderingMode(.alwaysTemplate)
$0.setSize(CGSize(width: 40, height: 40), animated: false)
$0.layer.cornerRadius = 8
$0.imageEdgeInsets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
}.onKeyboardEditingBegins {
$0.setSize(CGSize(width: 30, height: 30), animated: true)
}.onKeyboardEditingEnds {
$0.setSize(CGSize(width: 40, height: 40), animated: true)
}.onSelected {
$0.backgroundColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
$0.tintColor = .white
$0.tintColor = UIColor(colorLiteralRed: 15/255, green: 135/255, blue: 255/255, alpha: 1.0)
}.onDeselected {
$0.backgroundColor = .white
$0.tintColor = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1)
$0.tintColor = UIColor.lightGray
}.onTouchUpInside { _ in
print("Item Tapped")
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/MessageInputBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ open class MessageInputBar: UIView {
/// - Parameters:
/// - newValue: New widthAnchor constant
/// - animated: If the layout should be animated
open func setLeftStackViewWidthContant(to newValue: CGFloat, animated: Bool) {
open func setLeftStackViewWidthConstant(to newValue: CGFloat, animated: Bool) {
performLayout(animated) {
self.leftStackViewWidthContant = newValue
self.layoutStackViews([.left])
Expand All @@ -409,7 +409,7 @@ open class MessageInputBar: UIView {
/// - Parameters:
/// - newValue: New widthAnchor constant
/// - animated: If the layout should be animated
open func setRightStackViewWidthContant(to newValue: CGFloat, animated: Bool) {
open func setRightStackViewWidthConstant(to newValue: CGFloat, animated: Bool) {
performLayout(animated) {
self.rightStackViewWidthContant = newValue
self.layoutStackViews([.right])
Expand Down
80 changes: 29 additions & 51 deletions Sources/MessagesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ open class MessagesViewController: UIViewController {
open var messageInputBar = MessageInputBar()

private var messageInputBarCopy: MessageInputBar?

private var isFirstLayout: Bool = true

override open var canBecomeFirstResponder: Bool {
return true
Expand Down Expand Up @@ -64,17 +66,23 @@ open class MessagesViewController: UIViewController {

open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setupMessageInputBarCopy()
if isFirstLayout {
setupMessageInputBarCopy()
}
}

open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
addKeyboardObservers()
removeMessageInputBarCopy()
}

override open func viewDidLayoutSubviews() {
messagesCollectionView.contentInset.top = topLayoutGuide.length
open override func viewDidLayoutSubviews() {
// Hack to prevent animation of the contentInset after viewDidAppear
if isFirstLayout {
addKeyboardObservers()
messagesCollectionView.contentInset.bottom = messageInputBar.frame.height
isFirstLayout = false
}
}

// MARK: - Initializers
Expand Down Expand Up @@ -120,16 +128,14 @@ open class MessagesViewController: UIViewController {
}

private func setupConstraints() {

messagesCollectionView.translatesAutoresizingMaskIntoConstraints = false

let constraints: [NSLayoutConstraint] = [
messagesCollectionView.topAnchor.constraint(equalTo: view.topAnchor),
messagesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
messagesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
messagesCollectionView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor)
]
NSLayoutConstraint.activate(constraints)
messagesCollectionView.translatesAutoresizingMaskIntoConstraints = fals

let top = messagesCollectionView.topAnchor.constraint(equalTo: view.topAnchor, constant: topLayoutGuide.length)
let leading = messagesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor)
let trailing = messagesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
let bottom = messagesCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor)

NSLayoutConstraint.activate([top, bottom, trailing, leading])
}

// MARK: - MessageInputBar
Expand Down Expand Up @@ -179,16 +185,6 @@ extension MessagesViewController: UICollectionViewDataSource {

}

func configureMessageCell<T: UIView>(cell: MessageCollectionViewCell<T>) {
if let cellDelegate = messagesCollectionView.messageCellDelegate {
if cell.delegate == nil { cell.delegate = cellDelegate }
}
}

func configureTextCell(cell: TextMessageCell) {
configureMessageCell(cell: cell)
}

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

guard let messagesCollectionView = collectionView as? MessagesCollectionView else { return UICollectionViewCell() }
Expand Down Expand Up @@ -265,44 +261,26 @@ extension MessagesViewController: UICollectionViewDataSource {
extension MessagesViewController {

fileprivate func addKeyboardObservers() {

NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidChangeState), name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidChangeState), name: .UIKeyboardWillHide, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidChangeState), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidChangeState), name: .UIKeyboardWillChangeFrame, object: nil)

}

fileprivate func removeKeyboardObservers() {
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillChangeFrame, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
}

func handleKeyboardDidChangeState(_ notification: Notification) {

guard let keyboardEndFrame = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? CGRect else { return }
let keyboardFrame = self.view.convert(keyboardEndFrame, from: self.view.window)

switch notification.name {
case Notification.Name.UIKeyboardDidShow:
// Only runs once
messagesCollectionView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: messageInputBar.frame.height, right: 0)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
case Notification.Name.UIKeyboardDidChangeFrame, Notification.Name.UIKeyboardWillShow:
if (keyboardFrame.origin.y + keyboardFrame.size.height) > view.frame.size.height {
// Hardware keyboard is found
messagesCollectionView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: messageInputBar.frame.height, right: 0)
} else {
// Software keyboard is found
messagesCollectionView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: keyboardEndFrame.height, right: 0)
}
case Notification.Name.UIKeyboardWillHide:
messagesCollectionView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: messageInputBar.frame.height, right: 0)
default:
break

if (keyboardEndFrame.origin.y + keyboardEndFrame.size.height) > view.frame.size.height {
// Hardware keyboard is found
messagesCollectionView.contentInset.bottom = view.frame.size.height - keyboardEndFrame.origin.y
} else {
//Software keyboard is found
let bottomInset = keyboardEndFrame.height > messageInputBar.frame.height ? keyboardEndFrame.height : messageInputBar.frame.height
messagesCollectionView.contentInset.bottom = bottomInset
}

}

}

0 comments on commit 603a938

Please sign in to comment.