Skip to content

Commit 98afafe

Browse files
committed
Make the code support visionOS
1 parent 1bb7ef5 commit 98afafe

10 files changed

Lines changed: 93 additions & 48 deletions

MessageKit.xcodeproj/project.pbxproj

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@
7979
C72A8F522944400E006DB10F /* MessagesCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72A8F0A2944400E006DB10F /* MessagesCollectionView.swift */; };
8080
C72A8F532944400E006DB10F /* PlayButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72A8F0B2944400E006DB10F /* PlayButtonView.swift */; };
8181
C72A8F542944400E006DB10F /* BubbleCircle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72A8F0C2944400E006DB10F /* BubbleCircle.swift */; };
82-
C72A8F5A29444349006DB10F /* InputBarAccessoryView in Frameworks */ = {isa = PBXBuildFile; productRef = C72A8F5929444349006DB10F /* InputBarAccessoryView */; };
82+
C7951AFC2D39EC9300CEACA2 /* InputBarAccessoryView in Frameworks */ = {isa = PBXBuildFile; productRef = C7951AFB2D39EC9300CEACA2 /* InputBarAccessoryView */; };
8383
C79D579B296BF5790044D518 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C7CB28212943270000C8328F /* Assets.xcassets */; };
8484
/* End PBXBuildFile section */
8585

@@ -167,7 +167,7 @@
167167
isa = PBXFrameworksBuildPhase;
168168
buildActionMask = 2147483647;
169169
files = (
170-
C72A8F5A29444349006DB10F /* InputBarAccessoryView in Frameworks */,
170+
C7951AFC2D39EC9300CEACA2 /* InputBarAccessoryView in Frameworks */,
171171
);
172172
runOnlyForDeploymentPostprocessing = 0;
173173
};
@@ -397,7 +397,7 @@
397397
);
398398
name = MessageKit;
399399
packageProductDependencies = (
400-
C72A8F5929444349006DB10F /* InputBarAccessoryView */,
400+
C7951AFB2D39EC9300CEACA2 /* InputBarAccessoryView */,
401401
);
402402
productName = MessageKit;
403403
productReference = C72A8DF529443D1E006DB10F /* MessageKit.framework */;
@@ -446,7 +446,7 @@
446446
);
447447
mainGroup = C7CB27F0294324CA00C8328F;
448448
packageReferences = (
449-
C72A8F55294442C5006DB10F /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */,
449+
C7951AFA2D39EC8600CEACA2 /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */,
450450
);
451451
productRefGroup = C7CB27FE2943253B00C8328F /* Products */;
452452
projectDirPath = "";
@@ -633,11 +633,13 @@
633633
PROVISIONING_PROFILE_SPECIFIER = "";
634634
SDKROOT = iphoneos;
635635
SKIP_INSTALL = YES;
636+
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
637+
SUPPORTS_MACCATALYST = YES;
636638
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
637639
SWIFT_EMIT_LOC_STRINGS = YES;
638640
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
639641
SWIFT_VERSION = 5.0;
640-
TARGETED_DEVICE_FAMILY = "1,2";
642+
TARGETED_DEVICE_FAMILY = "1,2,7";
641643
VERSIONING_SYSTEM = "apple-generic";
642644
VERSION_INFO_PREFIX = "";
643645
};
@@ -712,11 +714,13 @@
712714
PROVISIONING_PROFILE_SPECIFIER = "";
713715
SDKROOT = iphoneos;
714716
SKIP_INSTALL = YES;
717+
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
718+
SUPPORTS_MACCATALYST = YES;
715719
SWIFT_COMPILATION_MODE = wholemodule;
716720
SWIFT_EMIT_LOC_STRINGS = YES;
717721
SWIFT_OPTIMIZATION_LEVEL = "-O";
718722
SWIFT_VERSION = 5.0;
719-
TARGETED_DEVICE_FAMILY = "1,2";
723+
TARGETED_DEVICE_FAMILY = "1,2,7";
720724
VALIDATE_PRODUCT = YES;
721725
VERSIONING_SYSTEM = "apple-generic";
722726
VERSION_INFO_PREFIX = "";
@@ -908,20 +912,20 @@
908912
/* End XCConfigurationList section */
909913

910914
/* Begin XCRemoteSwiftPackageReference section */
911-
C72A8F55294442C5006DB10F /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */ = {
915+
C7951AFA2D39EC8600CEACA2 /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */ = {
912916
isa = XCRemoteSwiftPackageReference;
913-
repositoryURL = "git@github.com:nathantannar4/InputBarAccessoryView.git";
917+
repositoryURL = "https://github.com/HaleXie/InputBarAccessoryView";
914918
requirement = {
915-
kind = upToNextMajorVersion;
916-
minimumVersion = 5.4.0;
919+
branch = visionOS;
920+
kind = branch;
917921
};
918922
};
919923
/* End XCRemoteSwiftPackageReference section */
920924

921925
/* Begin XCSwiftPackageProductDependency section */
922-
C72A8F5929444349006DB10F /* InputBarAccessoryView */ = {
926+
C7951AFB2D39EC9300CEACA2 /* InputBarAccessoryView */ = {
923927
isa = XCSwiftPackageProductDependency;
924-
package = C72A8F55294442C5006DB10F /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */;
928+
package = C7951AFA2D39EC8600CEACA2 /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */;
925929
productName = InputBarAccessoryView;
926930
};
927931
/* End XCSwiftPackageProductDependency section */

Sources/Controllers/MessagesViewController+Keyboard.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ internal extension MessagesViewController {
5050
removeKeyboardWillChangeFrameNotificationObserver()
5151
}
5252
NotificationCenter.default.removeObserver(self, name: UITextView.textDidBeginEditingNotification, object: nil)
53+
#if os(iOS)
5354
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
55+
#endif
5456
}
5557

5658
// MARK: - Notification Handlers
@@ -142,7 +144,11 @@ internal extension MessagesViewController {
142144
}
143145

144146
func requiredInitialScrollViewBottomInset() -> CGFloat {
147+
#if os(visionOS)
148+
let inputAccessoryViewHeight: CGFloat = 0
149+
#else
145150
let inputAccessoryViewHeight = inputAccessoryView?.frame.height ?? 0
151+
#endif
146152
return max(0, inputAccessoryViewHeight + additionalBottomInset - automaticallyAddedBottomInset)
147153
}
148154

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
/*
22
MIT License
3-
3+
44
Copyright (c) 2017-2019 MessageKit
5-
5+
66
Permission is hereby granted, free of charge, to any person obtaining a copy
77
of this software and associated documentation files (the "Software"), to deal
88
in the Software without restriction, including without limitation the rights
99
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1010
copies of the Software, and to permit persons to whom the Software is
1111
furnished to do so, subject to the following conditions:
12-
12+
1313
The above copyright notice and this permission notice shall be included in all
1414
copies or substantial portions of the Software.
15-
15+
1616
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1717
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1818
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -26,56 +26,56 @@ import Foundation
2626
import UIKit
2727

2828
internal extension MessagesViewController {
29-
29+
3030
// MARK: - Register / Unregister Observers
31-
31+
#if os(iOS)
3232
func addMenuControllerObservers() {
3333
NotificationCenter.default.addObserver(self, selector: #selector(MessagesViewController.menuControllerWillShow(_:)), name: UIMenuController.willShowMenuNotification, object: nil)
3434
}
35-
35+
3636
func removeMenuControllerObservers() {
3737
NotificationCenter.default.removeObserver(self, name: UIMenuController.willShowMenuNotification, object: nil)
3838
}
39-
39+
4040
// MARK: - Notification Handlers
41-
41+
4242
/// Show menuController and set target rect to selected bubble
4343
@objc
4444
private func menuControllerWillShow(_ notification: Notification) {
45-
45+
4646
guard let currentMenuController = notification.object as? UIMenuController,
47-
let selectedIndexPath = selectedIndexPathForMenu else { return }
48-
47+
let selectedIndexPath = selectedIndexPathForMenu else { return }
48+
4949
NotificationCenter.default.removeObserver(self, name: UIMenuController.willShowMenuNotification, object: nil)
5050
defer {
5151
NotificationCenter.default.addObserver(self,
5252
selector: #selector(MessagesViewController.menuControllerWillShow(_:)),
5353
name: UIMenuController.willShowMenuNotification, object: nil)
5454
selectedIndexPathForMenu = nil
5555
}
56-
56+
5757
currentMenuController.setMenuVisible(false, animated: false)
58-
58+
5959
guard let selectedCell = messagesCollectionView.cellForItem(at: selectedIndexPath) as? MessageContentCell else { return }
6060
let selectedCellMessageBubbleFrame = selectedCell.convert(selectedCell.messageContainerView.frame, to: view)
61-
61+
6262
var messageInputBarFrame: CGRect = .zero
6363
if let messageInputBarSuperview = messageInputBar.superview {
6464
messageInputBarFrame = view.convert(messageInputBar.frame, from: messageInputBarSuperview)
6565
}
66-
66+
6767
var topNavigationBarFrame: CGRect = navigationBarFrame
6868
if navigationBarFrame != .zero, let navigationBarSuperview = navigationController?.navigationBar.superview {
6969
topNavigationBarFrame = view.convert(navigationController!.navigationBar.frame, from: navigationBarSuperview)
7070
}
71-
71+
7272
let menuHeight = currentMenuController.menuFrame.height
73-
73+
7474
let selectedCellMessageBubblePlusMenuFrame = CGRect(selectedCellMessageBubbleFrame.origin.x, selectedCellMessageBubbleFrame.origin.y - menuHeight, selectedCellMessageBubbleFrame.size.width, selectedCellMessageBubbleFrame.size.height + 2 * menuHeight)
75-
75+
7676
var targetRect: CGRect = selectedCellMessageBubbleFrame
7777
currentMenuController.arrowDirection = .default
78-
78+
7979
/// Message bubble intersects with navigationBar and keyboard
8080
if selectedCellMessageBubblePlusMenuFrame.intersects(topNavigationBarFrame) && selectedCellMessageBubblePlusMenuFrame.intersects(messageInputBarFrame) {
8181
let centerY = (selectedCellMessageBubblePlusMenuFrame.intersection(messageInputBarFrame).minY + selectedCellMessageBubblePlusMenuFrame.intersection(topNavigationBarFrame).maxY) / 2
@@ -84,17 +84,24 @@ internal extension MessagesViewController {
8484
else if selectedCellMessageBubblePlusMenuFrame.intersects(topNavigationBarFrame) {
8585
currentMenuController.arrowDirection = .up
8686
}
87-
87+
8888
currentMenuController.setTargetRect(targetRect, in: view)
8989
currentMenuController.setMenuVisible(true, animated: true)
9090
}
91-
91+
9292
// MARK: - Helpers
93-
93+
9494
private var navigationBarFrame: CGRect {
9595
guard let navigationController = navigationController, !navigationController.navigationBar.isHidden else {
9696
return .zero
9797
}
9898
return navigationController.navigationBar.frame
9999
}
100+
#elseif os(visionOS)
101+
func addMenuControllerObservers() {
102+
}
103+
104+
func removeMenuControllerObservers() {
105+
}
106+
#endif
100107
}

Sources/Controllers/MessagesViewController.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecogni
7878
return true
7979
}
8080

81+
#if os(iOS)
8182
open override var inputAccessoryView: UIView? {
8283
return messageInputBar
8384
}
85+
#endif
8486

8587
open override var shouldAutorotate: Bool {
8688
return false
@@ -119,7 +121,9 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecogni
119121
internal var messageCollectionViewBottomInset: CGFloat = 0 {
120122
didSet {
121123
messagesCollectionView.contentInset.bottom = messageCollectionViewBottomInset
124+
#if os(iOS)
122125
messagesCollectionView.scrollIndicatorInsets.bottom = messageCollectionViewBottomInset
126+
#endif
123127
}
124128
}
125129

@@ -232,7 +236,9 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecogni
232236
private func setupDefaults() {
233237
extendedLayoutIncludesOpaqueBars = true
234238
view.backgroundColor = .collectionViewBackground
239+
#if os(iOS)
235240
messagesCollectionView.keyboardDismissMode = .interactive
241+
#endif
236242
messagesCollectionView.alwaysBounceVertical = true
237243
messagesCollectionView.backgroundColor = .collectionViewBackground
238244
if #available(iOS 13.0, *) {
@@ -465,15 +471,17 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecogni
465471
return layoutDelegate.footerViewSize(for: section, in: messagesCollectionView)
466472
}
467473

474+
// TODO: re-implement with - (nullable UIContextMenuConfiguration *)collectionView:(UICollectionView *)collectionView contextMenuConfigurationForItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths point:(CGPoint)point
475+
#if os(iOS)
468476
open func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool {
469477
guard let messagesDataSource = messagesCollectionView.messagesDataSource else { return false }
470-
478+
471479
if isSectionReservedForTypingIndicator(indexPath.section) {
472480
return false
473481
}
474-
482+
475483
let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
476-
484+
477485
switch message.kind {
478486
case .text, .attributedText, .emoji, .photo:
479487
selectedIndexPathForMenu = indexPath
@@ -482,21 +490,21 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecogni
482490
return false
483491
}
484492
}
485-
493+
486494
open func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
487495
if isSectionReservedForTypingIndicator(indexPath.section) {
488496
return false
489497
}
490498
return (action == NSSelectorFromString("copy:"))
491499
}
492-
500+
493501
open func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) {
494502
guard let messagesDataSource = messagesCollectionView.messagesDataSource else {
495503
fatalError(MessageKitError.nilMessagesDataSource)
496504
}
497505
let pasteBoard = UIPasteboard.general
498506
let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
499-
507+
500508
switch message.kind {
501509
case .text(let text), .emoji(let text):
502510
pasteBoard.string = text
@@ -508,6 +516,7 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UIGestureRecogni
508516
break
509517
}
510518
}
519+
#endif
511520

512521
// MARK: - Helpers
513522

Sources/Layout/MessagesCollectionViewFlowLayout.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout {
9090
}
9191

9292
private func setupObserver() {
93+
#if os(iOS)
9394
NotificationCenter.default.addObserver(self, selector: #selector(MessagesCollectionViewFlowLayout.handleOrientationChange(_:)), name: UIApplication.didChangeStatusBarOrientationNotification, object: nil)
95+
#endif
9496
}
9597

9698
// MARK: - Typing Indicator API

Sources/Models/LocationMessageSnapshotOptions.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,19 @@ import MapKit
2626

2727
/// An object grouping the settings used by the `MKMapSnapshotter` through the `LocationMessageDisplayDelegate`.
2828
public struct LocationMessageSnapshotOptions {
29-
29+
#if os(visionOS)
30+
public static let screenScale = UITraitCollection.current.displayScale
31+
#else
32+
public static let screenScale = UIScreen.main.scale
33+
#endif
3034
/// Initialize LocationMessageSnapshotOptions with given parameters
3135
///
3236
/// - Parameters:
3337
/// - showsBuildings: A Boolean value indicating whether the snapshot image should display buildings.
3438
/// - showsPointsOfInterest: A Boolean value indicating whether the snapshot image should display points of interest.
3539
/// - span: The span of the snapshot.
3640
/// - scale: The scale of the snapshot.
37-
public init(showsBuildings: Bool = false, showsPointsOfInterest: Bool = false, span: MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 0), scale: CGFloat = UIScreen.main.scale) {
41+
public init(showsBuildings: Bool = false, showsPointsOfInterest: Bool = false, span: MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 0), scale: CGFloat = LocationMessageSnapshotOptions.screenScale) {
3842
self.showsBuildings = showsBuildings
3943
self.showsPointsOfInterest = showsPointsOfInterest
4044
self.span = span

Sources/Views/AvatarView.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,14 @@ open class AvatarView: UIImageView {
9696
let height = frame.height
9797
if width == 0 || height == 0 {return UIImage()}
9898
var font = placeholderFont
99-
100-
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, UIScreen.main.scale)
99+
100+
#if os(visionOS)
101+
let scale = UITraitCollection.current.displayScale
102+
#else
103+
let scale = UIScreen.main.scale
104+
#endif
105+
106+
UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, scale)
101107
defer { UIGraphicsEndImageContext() }
102108
let context = UIGraphicsGetCurrentContext()!
103109

Sources/Views/Cells/AudioMessageCell.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ open class AudioMessageCell: MessageContentCell {
4848
}()
4949

5050
public lazy var activityIndicatorView: UIActivityIndicatorView = {
51-
let activityIndicatorView = UIActivityIndicatorView(style: .gray)
51+
let activityIndicatorView = UIActivityIndicatorView(style: .medium)
5252
activityIndicatorView.hidesWhenStopped = true
5353
activityIndicatorView.isHidden = true
5454
return activityIndicatorView

0 commit comments

Comments
 (0)