【问题标题】:How to combine Swift code(class) with Objective-C?如何将 Swift 代码(类)与 Objective-C 结合起来?
【发布时间】:2021-01-12 13:14:53
【问题描述】:

我使用包含在 CollectionView 和 swift 类中的 Swift 代码制作了一个项目,现在我在 obj-c 中制作了一个 collectionview,我想使用我旧 swift 项目中的一个类,如何将它结合起来swift 文件(类)与我当前的 obj-c 文件?在我的快速课程中,我还使用了委托,所以很难将这两者结合起来:)。

这是我的代码 - obj-c 中的 CollectionView:

#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

我的 Swift 文件/类:

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

【问题讨论】:

    标签: ios objective-c swift


    【解决方案1】:

    由于 Objective-C 文件不在 Swift 上下文中,并且需要导入每个新文件 *.h*.m,因此您必须在 Objective-C 文件中导入 *-Swift.h 才能导入 Swift 类。

    正如苹果所说:

    您不需要做任何特别的事情来创建生成的标头 - 只需将其导入即可在您的 Objective-C 代码中使用其内容

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

    Swift 文件和 Objective-C 文件在同一个项目中

    • 如果你的项目名称是MyBeautifulApp,那么你要导入
    #import MyBeautifulApp-Swift.h
    

    从那里使用 Swift 类。

    与 Objective-C 项目不同的项目中的 Swift 文件

    但是如果你的 Swift 文件是一个框架而不是目标,你必须使用

    #import <MyBeautifulApp/MyBeautifulApp-Swift.h>
    

    之后:

    • 在同一框架内将 Swift 代码导入到 Objective-C: 在 Build Settings 下的 Packaging 中,确保该框架目标的 Defines Module 设置设置为 Yes

    如果我帮助了你,请告诉我。

    【讨论】:

    • 首先感谢您的回答:) 它让我对 swift 与 objc 有了更多的了解,但我的问题是 Idk 如何在我的 objc 的 swift 类中使用我的委托方法代码:(
    • 对不起!所以让我看看我是否明白了:你必须在 Objective-C 类中实现sendEventForCell(atIndexPath:) 好吗?你试过@objc 那个函数名吗? @objc func sendEventForCell(atIndexPath indexPath: IndexPath)
    • 是的,我在每个方法中都添加了 objc,哈哈,我只是想了解如何在我的 objc 文件中实现该委托方法,这对 objc 来说有点新 :)
    • 您是否在协议范围和函数名称中添加了@objc?它必须同时添加。
    • ye :\ 我会尝试找出它是如何工作的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 2014-07-28
    相关资源
    最近更新 更多