Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
581 views
in Technique[技术] by (71.8m points)

ios - How to combine Swift code(class) with Objective-C?

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
       }
    
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c

Swift files and Objective-C files in same project

  • If your project name is MyBeautifulApp, so you're going to import
#import MyBeautifulApp-Swift.h

to use Swift classes from there.

Swift files in different project from Objective-C project

But if your Swift file is a framework instead of target, you must use

#import <MyBeautifulApp/MyBeautifulApp-Swift.h>

after doing that:

  • Import Swift code into Objective-C within the same framework: Under Build Settings, in Packaging, make sure the Defines Module setting for that framework target is set to Yes

Let me know if I helped you please.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...