зеркало из https://github.com/nextcloud/talk-ios.git
Add CallFlowLayout and remove NBMPeersFlowLayout
Signed-off-by: Marcel Müller <marcel-mueller@gmx.de>
This commit is contained in:
Родитель
3438da964d
Коммит
c7ed92b0fd
|
@ -47,6 +47,7 @@
|
|||
1F98DF9C28E7484700E05174 /* ReferenceDeckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F98DF9B28E7484700E05174 /* ReferenceDeckView.swift */; };
|
||||
1F98DF9E28E7485000E05174 /* ReferenceDeckView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1F98DF9D28E7485000E05174 /* ReferenceDeckView.xib */; };
|
||||
1FA20C8A284001D80062B4F3 /* DebounceWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FA20C89284001D80062B4F3 /* DebounceWebView.swift */; };
|
||||
1FA732FC2966CBB7003D2103 /* CallFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FA732FB2966CBB7003D2103 /* CallFlowLayout.swift */; };
|
||||
1FB52E762842C75E00AC741B /* QRCodeLoginController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FB52E752842C75E00AC741B /* QRCodeLoginController.swift */; };
|
||||
1FB6678F28CE381300D29F8D /* SubtitleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FB6678E28CE381300D29F8D /* SubtitleTableViewCell.swift */; };
|
||||
1FD9182928C55A73009092AB /* BGTaskHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD9182828C55A73009092AB /* BGTaskHelper.swift */; };
|
||||
|
@ -195,7 +196,6 @@
|
|||
2C78EFA11F828C41008AFA74 /* CallViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C78EF9F1F828C41008AFA74 /* CallViewController.xib */; };
|
||||
2C78EFA51F86FF4A008AFA74 /* CallParticipantViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C78EFA31F86FF4A008AFA74 /* CallParticipantViewCell.m */; };
|
||||
2C78EFA61F86FF4A008AFA74 /* CallParticipantViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C78EFA41F86FF4A008AFA74 /* CallParticipantViewCell.xib */; };
|
||||
2C78EFA91F87EF39008AFA74 /* NBMPeersFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C78EFA81F87EF39008AFA74 /* NBMPeersFlowLayout.m */; };
|
||||
2C7A1237200E0A5700864818 /* UserSettingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C7A1235200E0A5700864818 /* UserSettingsTableViewCell.xib */; };
|
||||
2C7A12422017872600864818 /* AddParticipantsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C7A12402017872600864818 /* AddParticipantsTableViewController.m */; };
|
||||
2C7A12432017872600864818 /* AddParticipantsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C7A12412017872600864818 /* AddParticipantsTableViewController.xib */; };
|
||||
|
@ -402,6 +402,7 @@
|
|||
1F98DF9B28E7484700E05174 /* ReferenceDeckView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReferenceDeckView.swift; sourceTree = "<group>"; };
|
||||
1F98DF9D28E7485000E05174 /* ReferenceDeckView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReferenceDeckView.xib; sourceTree = "<group>"; };
|
||||
1FA20C89284001D80062B4F3 /* DebounceWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebounceWebView.swift; sourceTree = "<group>"; };
|
||||
1FA732FB2966CBB7003D2103 /* CallFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallFlowLayout.swift; sourceTree = "<group>"; };
|
||||
1FB52E752842C75E00AC741B /* QRCodeLoginController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeLoginController.swift; sourceTree = "<group>"; };
|
||||
1FB6678E28CE381300D29F8D /* SubtitleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubtitleTableViewCell.swift; sourceTree = "<group>"; };
|
||||
1FD9182828C55A73009092AB /* BGTaskHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGTaskHelper.swift; sourceTree = "<group>"; };
|
||||
|
@ -589,8 +590,6 @@
|
|||
2C78EFA21F86FF4A008AFA74 /* CallParticipantViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallParticipantViewCell.h; sourceTree = "<group>"; };
|
||||
2C78EFA31F86FF4A008AFA74 /* CallParticipantViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CallParticipantViewCell.m; sourceTree = "<group>"; };
|
||||
2C78EFA41F86FF4A008AFA74 /* CallParticipantViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CallParticipantViewCell.xib; sourceTree = "<group>"; };
|
||||
2C78EFA71F87EF39008AFA74 /* NBMPeersFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NBMPeersFlowLayout.h; sourceTree = "<group>"; };
|
||||
2C78EFA81F87EF39008AFA74 /* NBMPeersFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NBMPeersFlowLayout.m; sourceTree = "<group>"; };
|
||||
2C7A1235200E0A5700864818 /* UserSettingsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UserSettingsTableViewCell.xib; sourceTree = "<group>"; };
|
||||
2C7A123F2017872600864818 /* AddParticipantsTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AddParticipantsTableViewController.h; sourceTree = "<group>"; };
|
||||
2C7A12402017872600864818 /* AddParticipantsTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AddParticipantsTableViewController.m; sourceTree = "<group>"; };
|
||||
|
@ -1145,8 +1144,6 @@
|
|||
2C78EF9D1F828C41008AFA74 /* CallViewController.h */,
|
||||
2C78EF9E1F828C41008AFA74 /* CallViewController.m */,
|
||||
2C78EF9F1F828C41008AFA74 /* CallViewController.xib */,
|
||||
2C78EFA71F87EF39008AFA74 /* NBMPeersFlowLayout.h */,
|
||||
2C78EFA81F87EF39008AFA74 /* NBMPeersFlowLayout.m */,
|
||||
2C78EF9A1F826B22008AFA74 /* NCCallController.h */,
|
||||
2C78EF9B1F826B22008AFA74 /* NCCallController.m */,
|
||||
2C8CDD0421C2EDE8004E2997 /* AvatarBackgroundImageView.h */,
|
||||
|
@ -1156,6 +1153,7 @@
|
|||
2C4DE9F021F732B40096940D /* NCAudioController.h */,
|
||||
2C4DE9F121F732B40096940D /* NCAudioController.m */,
|
||||
2C4446FA265D5BEF00DF1DBC /* CallConstants.h */,
|
||||
1FA732FB2966CBB7003D2103 /* CallFlowLayout.swift */,
|
||||
);
|
||||
name = Calls;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1883,7 +1881,6 @@
|
|||
2C0574851EDD9E8E00D9E7F2 /* AppDelegate.m in Sources */,
|
||||
2C4987BD21E640E20060AC27 /* CallKitManager.m in Sources */,
|
||||
2C4446F3265D51A600DF1DBC /* NCPushNotificationsUtils.m in Sources */,
|
||||
2C78EFA91F87EF39008AFA74 /* NBMPeersFlowLayout.m in Sources */,
|
||||
2C1ABDE5257F883400AEDFB6 /* ABContact.m in Sources */,
|
||||
2CA1CCDB1F1F6FCA002FE6A2 /* RoomTableViewCell.m in Sources */,
|
||||
2C5BFBEF288A947900E75118 /* PollVotingView.swift in Sources */,
|
||||
|
@ -1984,6 +1981,7 @@
|
|||
DA66582D27B6A73800B46B11 /* UserProfileTableViewController+DelegateMethods.swift in Sources */,
|
||||
1F5CDF642584E78900B0026E /* NCChatFileStatus.m in Sources */,
|
||||
2CBF82C11FD5AE3F00636459 /* NCPushProxySessionManager.m in Sources */,
|
||||
1FA732FC2966CBB7003D2103 /* CallFlowLayout.swift in Sources */,
|
||||
2C78EF951F7E70EB008AFA74 /* NCPeerConnection.m in Sources */,
|
||||
2C06BF6C20AEB0030031EB46 /* RoundedNumberView.m in Sources */,
|
||||
2CEDA88926F10BB20044552B /* UserStatusMessageViewController.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
//
|
||||
// Copyright (c) 2022 Marcel Müller <marcel-mueller@gmx.de>
|
||||
//
|
||||
// Author Marcel Müller <marcel-mueller@gmx.de>
|
||||
//
|
||||
// GNU GPL version 3 or any later version
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// Based on https://stackoverflow.com/a/41409642
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers
|
||||
class CallFlowLayout: UICollectionViewFlowLayout {
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
commonInit()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
commonInit()
|
||||
}
|
||||
|
||||
func commonInit() {
|
||||
self.minimumInteritemSpacing = 10
|
||||
self.minimumLineSpacing = 10
|
||||
self.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
|
||||
}
|
||||
|
||||
func isPortrait() -> Bool {
|
||||
guard let collectionView = collectionView else { return false }
|
||||
|
||||
return collectionView.bounds.size.width < collectionView.bounds.size.height
|
||||
}
|
||||
|
||||
func numberOfColumns(for numberOfCells: Int) -> Int {
|
||||
if isPortrait() {
|
||||
if numberOfCells <= 2 {
|
||||
return 1
|
||||
} else if numberOfCells <= 6 {
|
||||
return 2
|
||||
}
|
||||
|
||||
return 3
|
||||
}
|
||||
|
||||
if numberOfCells == 1 {
|
||||
return 1
|
||||
} else if numberOfCells <= 2 || numberOfCells == 4 {
|
||||
return 2
|
||||
} else if numberOfCells == 3 || numberOfCells == 5 {
|
||||
return 3
|
||||
}
|
||||
|
||||
return 4
|
||||
}
|
||||
|
||||
override func prepare() {
|
||||
super.prepare()
|
||||
|
||||
guard let collectionView = collectionView else { return }
|
||||
|
||||
let contentSize = collectionView.bounds.size
|
||||
let numberOfCells = collectionView.numberOfItems(inSection: 0)
|
||||
let numberOfColumns = numberOfColumns(for: numberOfCells)
|
||||
let numberOfRows = (CGFloat(numberOfCells) / CGFloat(numberOfColumns)).rounded(.up)
|
||||
|
||||
// Calculate cell width
|
||||
let sectionInsetWidth = sectionInset.left + sectionInset.right
|
||||
let safeAreaInsetWidth = collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
|
||||
let marginsAndInsetsWidth = sectionInsetWidth + safeAreaInsetWidth + minimumInteritemSpacing * CGFloat(numberOfColumns - 1)
|
||||
let itemWidth = ((contentSize.width - marginsAndInsetsWidth) / CGFloat(numberOfColumns)).rounded(.down)
|
||||
|
||||
// Calculate cell height
|
||||
let sectionInsetHeight = sectionInset.top + sectionInset.bottom
|
||||
let safeAreaInsetHeight = collectionView.safeAreaInsets.top + collectionView.safeAreaInsets.bottom
|
||||
let marginsAndInsetsHeight = sectionInsetHeight + safeAreaInsetHeight + minimumLineSpacing * CGFloat(numberOfRows + 1)
|
||||
var itemHeight = ((contentSize.height - marginsAndInsetsHeight) / CGFloat(numberOfRows)).rounded(.down)
|
||||
|
||||
// Enfore minimum cell height
|
||||
if itemHeight < kCallParticipantCellMinHeight {
|
||||
itemHeight = kCallParticipantCellMinHeight
|
||||
}
|
||||
|
||||
itemSize = CGSize(width: itemWidth, height: itemHeight)
|
||||
}
|
||||
|
||||
override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext {
|
||||
let context = super.invalidationContext(forBoundsChange: newBounds)
|
||||
|
||||
if let context = context as? UICollectionViewFlowLayoutInvalidationContext {
|
||||
context.invalidateFlowLayoutDelegateMetrics = newBounds.size != collectionView?.bounds.size
|
||||
}
|
||||
|
||||
return context
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,6 @@
|
|||
|
||||
#import "CallKitManager.h"
|
||||
#import "CallParticipantViewCell.h"
|
||||
#import "NBMPeersFlowLayout.h"
|
||||
#import "NCAPIController.h"
|
||||
#import "NCAppBranding.h"
|
||||
#import "NCAudioController.h"
|
||||
|
@ -46,6 +45,8 @@
|
|||
#import "NCSignalingMessage.h"
|
||||
#import "NCUtils.h"
|
||||
|
||||
#import "NextcloudTalk-Swift.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, CallState) {
|
||||
CallStateJoining,
|
||||
CallStateWaitingParticipants,
|
||||
|
@ -164,6 +165,7 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
[self.closeScreensharingButton.layer setCornerRadius:16.0f];
|
||||
|
||||
[self.collectionView.layer setCornerRadius:30.0f];
|
||||
[self.collectionView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentAlways];
|
||||
|
||||
_airplayView = [[AVRoutePickerView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
|
||||
_airplayView.tintColor = [UIColor whiteColor];
|
||||
|
@ -1291,14 +1293,6 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
return cell;
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGRect frame = [NBMPeersFlowLayout frameForWithNumberOfItems:_peersInCall.count
|
||||
row:indexPath.row
|
||||
contentSize:self.collectionView.frame.size];
|
||||
return frame.size;
|
||||
}
|
||||
|
||||
-(void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CallParticipantViewCell *participantCell = (CallParticipantViewCell *)cell;
|
||||
|
@ -1307,11 +1301,6 @@ typedef NS_ENUM(NSInteger, CallState) {
|
|||
[self updateParticipantCell:participantCell withPeerConnection:peerConnection];
|
||||
}
|
||||
|
||||
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
|
||||
{
|
||||
return kCallViewParticipantLineSpacing;
|
||||
}
|
||||
|
||||
#pragma mark - Call Controller delegate
|
||||
|
||||
- (void)callControllerDidJoinCall:(NCCallController *)callController
|
||||
|
|
|
@ -192,7 +192,7 @@
|
|||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="aUh-Z0-hO6">
|
||||
<rect key="frame" x="0.0" y="84" width="834" height="1028"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" sectionInsetReference="safeArea" id="iSf-tu-VMU">
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" sectionInsetReference="safeArea" id="iSf-tu-VMU" customClass="CallFlowLayout" customModule="NextcloudTalk" customModuleProvider="target">
|
||||
<size key="itemSize" width="50" height="50"/>
|
||||
<size key="headerReferenceSize" width="0.0" height="0.0"/>
|
||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
extern CGFloat const kCallViewParticipantLineSpacing;
|
||||
|
||||
@interface NBMPeersFlowLayout : UICollectionViewFlowLayout
|
||||
|
||||
+ (CGRect)frameForWithNumberOfItems:(NSUInteger)numberOfItems row:(NSUInteger)row contentSize:(CGSize)contentSize;
|
||||
|
||||
@end
|
|
@ -1,223 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
#import "NBMPeersFlowLayout.h"
|
||||
|
||||
#import "CallParticipantViewCell.h"
|
||||
|
||||
CGFloat const kCallViewParticipantLineSpacing = 8.0;
|
||||
|
||||
@interface NBMPeersFlowLayout ()
|
||||
|
||||
@property (assign, nonatomic) BOOL isActvive;
|
||||
|
||||
// Containers for keeping track of changing items
|
||||
@property (nonatomic, strong) NSMutableArray *insertedIndexPaths;
|
||||
@property (nonatomic, strong) NSMutableArray *removedIndexPaths;
|
||||
@property (nonatomic, strong) NSMutableArray *insertedSectionIndices;
|
||||
@property (nonatomic, strong) NSMutableArray *removedSectionIndices;
|
||||
|
||||
// Caches for keeping current/previous attributes
|
||||
@property (nonatomic, strong) NSMutableDictionary *currentCellAttributes;
|
||||
@property (nonatomic, strong) NSMutableDictionary *currentSupplementaryAttributesByKind;
|
||||
@property (nonatomic, strong) NSMutableDictionary *cachedCellAttributes;
|
||||
@property (nonatomic, strong) NSMutableDictionary *cachedSupplementaryAttributesByKind;
|
||||
|
||||
@end
|
||||
|
||||
@implementation NBMPeersFlowLayout
|
||||
|
||||
- (CGSize)collectionViewContentSize {
|
||||
|
||||
return self.collectionView.frame.size;
|
||||
}
|
||||
|
||||
-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)prepareLayout {
|
||||
|
||||
// // Deep-copy attributes in current cache
|
||||
// self.cachedCellAttributes = [[NSMutableDictionary alloc] initWithDictionary:self.currentCellAttributes copyItems:YES];
|
||||
// self.cachedSupplementaryAttributesByKind = [NSMutableDictionary dictionary];
|
||||
// [self.currentSupplementaryAttributesByKind enumerateKeysAndObjectsUsingBlock:^(NSString *kind, NSMutableDictionary * attribByPath, BOOL *stop) {
|
||||
// NSMutableDictionary * cachedAttribByPath = [[NSMutableDictionary alloc] initWithDictionary:attribByPath copyItems:YES];
|
||||
// [self.cachedSupplementaryAttributesByKind setObject:cachedAttribByPath forKey:kind];
|
||||
// }];
|
||||
//
|
||||
// self.minimumInteritemSpacing = 2;
|
||||
// self.minimumLineSpacing = 2;
|
||||
}
|
||||
|
||||
- (void)invalidateLayout {
|
||||
|
||||
[super invalidateLayout];
|
||||
self.isActvive = NO;
|
||||
}
|
||||
|
||||
+ (NSUInteger )columnsWithWithNumberOfItems:(NSUInteger )numbers isPortrait:(BOOL)isPortrait{
|
||||
|
||||
int countOfColumns = -1;
|
||||
|
||||
if (isPortrait) {
|
||||
|
||||
if (numbers <= 2 ){
|
||||
|
||||
countOfColumns = 1;
|
||||
}
|
||||
else if (numbers <= 6) {
|
||||
|
||||
countOfColumns = 2;
|
||||
}
|
||||
else {
|
||||
|
||||
countOfColumns = 3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (numbers == 1 ) {
|
||||
|
||||
countOfColumns = 1;
|
||||
|
||||
} else if (numbers <= 2 || numbers == 4) {
|
||||
|
||||
countOfColumns = 2;
|
||||
|
||||
} else if (numbers == 3 || numbers == 5) {
|
||||
|
||||
countOfColumns = 3;
|
||||
|
||||
} else {
|
||||
|
||||
countOfColumns = 4;
|
||||
}
|
||||
}
|
||||
|
||||
return countOfColumns;
|
||||
}
|
||||
|
||||
+ (CGRect)frameForWithNumberOfItems:(NSUInteger)numberOfItems row:(NSUInteger)row contentSize:(CGSize)contentSize {
|
||||
|
||||
BOOL isPortrait = contentSize.width < contentSize.height;
|
||||
NSUInteger columns = [NBMPeersFlowLayout columnsWithWithNumberOfItems:numberOfItems
|
||||
isPortrait:isPortrait];
|
||||
|
||||
// Only use a border if there's more than one participant, otherwise go fullscreen
|
||||
// For X we take half the spacing, because both neighbour cells will have a border
|
||||
NSUInteger borderX = numberOfItems == 1 ? 0 : kCallViewParticipantLineSpacing / 2;
|
||||
NSUInteger borderY = numberOfItems == 1 ? 0 : kCallViewParticipantLineSpacing;
|
||||
|
||||
NSUInteger rows = ceil((float)numberOfItems / (float)columns);
|
||||
|
||||
CGFloat h = (contentSize.height - ((rows + 1) * borderY)) / rows;
|
||||
CGFloat w = (contentSize.width - ((columns + 1) * borderX)) / columns ;
|
||||
|
||||
h = (h < kCallParticipantCellMinHeight) ? kCallParticipantCellMinHeight : h;
|
||||
|
||||
NSUInteger line = row == 0 ? 0 : row / columns;
|
||||
NSUInteger _r = row % columns;
|
||||
|
||||
NSUInteger xOffset = w * _r;
|
||||
NSUInteger yOffset = ceil(line == 0 ? 0 : h * line);
|
||||
|
||||
NSUInteger xBorderOffset = borderX * (_r + 1) ;
|
||||
NSUInteger yBorderOffset = borderY * (line + 1);
|
||||
|
||||
NSUInteger mod = numberOfItems % columns;
|
||||
|
||||
NSUInteger centered = numberOfItems - mod;
|
||||
|
||||
if (row >= centered) {
|
||||
|
||||
CGFloat centerX = contentSize.width / 2;
|
||||
xBorderOffset = centerX - mod * w/2;
|
||||
|
||||
}
|
||||
|
||||
CGRect result = CGRectMake(xOffset + xBorderOffset , yOffset + yBorderOffset, w , h);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
|
||||
|
||||
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
|
||||
|
||||
NSInteger items = [self.collectionView.dataSource collectionView:self.collectionView
|
||||
numberOfItemsInSection:0];
|
||||
|
||||
[attributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes * attributes, NSUInteger idx, BOOL * stop) {
|
||||
|
||||
CGRect frame = [NBMPeersFlowLayout frameForWithNumberOfItems:items
|
||||
row:idx
|
||||
contentSize:self.collectionView.frame.size];
|
||||
|
||||
if (attributes.representedElementCategory == UICollectionElementCategoryCell)
|
||||
{
|
||||
attributes.frame = frame;
|
||||
[self.currentCellAttributes setObject:attributes
|
||||
forKey:attributes.indexPath];
|
||||
}
|
||||
}];
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (void)finalizeCollectionViewUpdates
|
||||
{
|
||||
[super finalizeCollectionViewUpdates];
|
||||
|
||||
self.insertedIndexPaths = nil;
|
||||
self.removedIndexPaths = nil;
|
||||
self.insertedSectionIndices = nil;
|
||||
self.removedSectionIndices = nil;
|
||||
}
|
||||
|
||||
// center last row elements by collectionView center
|
||||
- (void)centerLastRowElements:(NSArray *)attributes {
|
||||
|
||||
CGFloat attributeWidth = ((UICollectionViewLayoutAttributes *)attributes[0]).frame.size.width;
|
||||
CGFloat centerX = self.collectionView.center.x;
|
||||
CGFloat offsetByX = centerX - attributes.count * attributeWidth/2; // shift by half sum of lowest row elements width
|
||||
|
||||
for (NSUInteger i = attributes.count; i != 0; i--) { // from left to right
|
||||
// first element will be leftmost at display
|
||||
UICollectionViewLayoutAttributes *currentAttribute = attributes[attributes.count - i];
|
||||
|
||||
currentAttribute.frame = CGRectMake(offsetByX,
|
||||
currentAttribute.frame.origin.y,
|
||||
currentAttribute.frame.size.width,
|
||||
currentAttribute.frame.size.height);
|
||||
|
||||
offsetByX += attributeWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/// arrange elements in row by full width
|
||||
- (void)arrangeLastRowElements:(NSArray *)attributes width:(CGFloat)width {
|
||||
|
||||
for (UICollectionViewLayoutAttributes *attribute in attributes) {
|
||||
attribute.size = CGSizeMake(width/attributes.count, attribute.size.height);
|
||||
}
|
||||
|
||||
[self centerLastRowElements:attributes];
|
||||
|
||||
}
|
||||
|
||||
@end
|
|
@ -24,6 +24,7 @@
|
|||
#define NextcloudTalk_Bridging_Header_h
|
||||
|
||||
#import "AvatarHeaderView.h"
|
||||
#import "CallParticipantViewCell.h"
|
||||
#import "DetailedOptionsSelectorTableViewController.h"
|
||||
#import "DirectoryTableViewCell.h"
|
||||
#import "HeaderWithButton.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче