Reputation: 81
I made a project with Swift code which was included with CollectionView and a swift class, now I made a collectionview in obj-c and I would like to use a class from my old swift project, how is it possible to combine that swift file(class) with my current obj-c file? In my swift class I also used delegates so kinda found it hard to combine these two :).
Here's my code - CollectionView in obj-c:
#import "ViewController.h"
#import "CollectionViewTest-Swift.h"
@interface ViewController ()<UICollectionViewDelegate, UICollectionViewDataSource>
@property NSArray *image_Arr;
@property NSArray *label_Arr;
@end
@implementation ViewController
{
ImpressionStalker *impressionEventStalker;
}
@synthesize Collection_view;
- (void)viewDidLoad {
[super viewDidLoad];
// collectionView.contentInset = UIEdgeInsets(top: 20, left: 0, bottom: 0, right: 0)
// impressionEventStalker = ImpressionStalker(minimumPercentageOfCell: 0.70, collectionView: collectionView, delegate: self)
_image_Arr = [ [NSArray alloc] initWithObjects:@"image_1",@"image_2",@"image_3",@"image_4",@"image_5", nil];
_label_Arr = [ [NSArray alloc] initWithObjects:@"0 Comments",@"2 Comments",@"4 Comments",@"0 Comments",@"5 Comments", nil];
impressionEventStalker = [[ImpressionStalker alloc]initWithMinimumPercentageOfCell:0.70 collectionView:self.Collection_view delegate: self];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _image_Arr.count;
}
// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL_ID" forIndexPath:indexPath];
UIImageView *Image_View = (UIImageView *) [cell viewWithTag:100];
UILabel *Label = (UILabel *) [cell viewWithTag:101];
Image_View.image = [UIImage imageNamed:[_image_Arr objectAtIndex:indexPath.row]];
Label.text = [_label_Arr objectAtIndex:indexPath.row];
return cell;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
@end
my Swift File/Class:
import Foundation
import UIKit
@objc
protocol ImpressionStalkerDelegate:NSObjectProtocol {
func sendEventForCell(atIndexPath indexPath:IndexPath)
}
protocol ImpressionItem {
func getUniqueId()->String
}
@objc
class ImpressionStalker: NSObject {
//MARK: Variables & Constants
let minimumPercentageOfCell: CGFloat
weak var collectionView: UICollectionView?
static var alreadySentIdentifiers = [String]()
weak var delegate: ImpressionStalkerDelegate?
//MARK: Initializer
@objc
init(minimumPercentageOfCell: CGFloat, collectionView: UICollectionView, delegate:ImpressionStalkerDelegate ) {
self.minimumPercentageOfCell = minimumPercentageOfCell
self.collectionView = collectionView
self.delegate = delegate
}
// Checks which cell is visible:
@objc
func stalkCells() {
for cell in collectionView!.visibleCells {
if let visibleCell = cell as? UICollectionViewCell & ImpressionItem {
let visiblePercentOfCell = percentOfVisiblePart(ofCell: visibleCell, inCollectionView: collectionView!)
if visiblePercentOfCell >= minimumPercentageOfCell, !ImpressionStalker.alreadySentIdentifiers.contains(visibleCell.getUniqueId()){ // >0.70 and not seen yet then...
guard let indexPath = collectionView!.indexPath(for: visibleCell), let delegate = delegate else {
continue
}
print(indexPath)
delegate.sendEventForCell(atIndexPath: indexPath) // send the cell's index since its visible.
ImpressionStalker.alreadySentIdentifiers.append(visibleCell.getUniqueId()) // to avoid double events to show up.
}
}
}
}
// Func Which Calculate the % Of Visible of each Cell:
@objc
private func percentOfVisiblePart(ofCell cell:UICollectionViewCell, inCollectionView collectionView:UICollectionView) -> CGFloat{
guard let indexPathForCell = collectionView.indexPath(for: cell),
let layoutAttributes = collectionView.layoutAttributesForItem(at: indexPathForCell) else {
return CGFloat.leastNonzeroMagnitude
}
let cellFrameInSuper = collectionView.convert(layoutAttributes.frame, to: collectionView.superview)
let interSectionRect = cellFrameInSuper.intersection(collectionView.frame)
let percentOfIntersection: CGFloat = interSectionRect.height/cellFrameInSuper.height
return percentOfIntersection
}
}
Upvotes: 1
Views: 1177
Reputation: 41
As a Objective-C file isn't in context for Swift and requires to import every new file *.h
or *.m
, you've to import *-Swift.h
in your Objective-C file to import Swift classes.
As Apple says:
You don't need to do anything special to create the generated header — Just import it to use its contents in your Objective-C code
MyBeautifulApp
, so you're going to import#import MyBeautifulApp-Swift.h
to use Swift classes from there.
But if your Swift file is a framework instead of target, you must use
#import <MyBeautifulApp/MyBeautifulApp-Swift.h>
after doing that:
Let me know if I helped you please.
Upvotes: 2