anyline-ocr-react-native-module 53.2.0 → 54.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/android/.gradle/7.6/checksums/checksums.lock +0 -0
  2. package/android/.gradle/7.6/checksums/md5-checksums.bin +0 -0
  3. package/android/.gradle/7.6/checksums/sha1-checksums.bin +0 -0
  4. package/android/.gradle/7.6/dependencies-accessors/dependencies-accessors.lock +0 -0
  5. package/android/.gradle/7.6/dependencies-accessors/gc.properties +0 -0
  6. package/android/.gradle/7.6/executionHistory/executionHistory.lock +0 -0
  7. package/android/.gradle/7.6/fileChanges/last-build.bin +0 -0
  8. package/android/.gradle/7.6/fileHashes/fileHashes.bin +0 -0
  9. package/android/.gradle/7.6/fileHashes/fileHashes.lock +0 -0
  10. package/android/.gradle/7.6/gc.properties +0 -0
  11. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  12. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  13. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  14. package/android/.gradle/config.properties +2 -0
  15. package/android/.gradle/vcs-1/gc.properties +0 -0
  16. package/android/.idea/compiler.xml +6 -0
  17. package/android/.idea/gradle.xml +17 -0
  18. package/android/.idea/migrations.xml +10 -0
  19. package/android/.idea/misc.xml +10 -0
  20. package/android/.idea/other.xml +296 -0
  21. package/android/.idea/vcs.xml +6 -0
  22. package/android/build.gradle +1 -1
  23. package/android/local.properties +8 -0
  24. package/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java +16 -2
  25. package/android/src/main/java/com/anyline/reactnative/ScanActivity.java +15 -2
  26. package/ios/ALJsonUIConfiguration.m +3 -0
  27. package/ios/ALPluginHelper.h +1 -3
  28. package/ios/ALPluginHelper.m +27 -59
  29. package/ios/ALPluginScanViewController.h +1 -0
  30. package/ios/ALPluginScanViewController.m +23 -1
  31. package/ios/AnylineReact.podspec +3 -3
  32. package/ios/AnylineSDKPlugin.m +31 -42
  33. package/package.json +8 -8
  34. package/ios/ALNFCScanViewController.h +0 -14
  35. package/ios/ALNFCScanViewController.m +0 -452
@@ -1,452 +0,0 @@
1
- #import <Anyline/Anyline.h>
2
- #import "ALNFCScanViewController.h"
3
- #import "ALPluginHelper.h"
4
- #import "AnylineSDKPlugin.h"
5
-
6
-
7
- API_AVAILABLE(ios(13.0))
8
- @interface ALNFCScanViewController () <ALNFCDetectorDelegate, ALScanPluginDelegate, ALScanViewDelegate>
9
-
10
- @property (nonatomic, strong) ALPluginCallback callback;
11
-
12
- @property (nonatomic, strong) NSDictionary *config;
13
-
14
- @property (nonatomic, copy) NSString *licenseKey;
15
-
16
- @property (nonatomic, strong) ALScanView *scanView;
17
-
18
- @property (nonatomic, strong) ALScanViewPlugin *mrzScanViewPlugin;
19
-
20
- @property (nonatomic, strong) ALNFCDetector *nfcDetector;
21
-
22
- // the result from NFC scanning is retained while NFC reading is initiated, and the results aggregated later
23
- @property (nonatomic, strong) NSMutableDictionary *resultDict;
24
-
25
- @property (nonatomic, strong) ALJSONUIConfiguration *uiConfig;
26
-
27
- @property (nonatomic, strong) UIView *hintView;
28
-
29
- @property (nonatomic, strong) UILabel *hintViewLabel;
30
-
31
- @property (nonatomic, strong) NSLayoutConstraint *labelHorizontalOffsetConstraint;
32
-
33
- @property (nonatomic, strong) NSLayoutConstraint *labelVerticalOffsetConstraint;
34
-
35
- @property (nonatomic, strong) UIButton *doneButton;
36
-
37
- // keep the last values we read from the MRZ so we can retry reading NFC
38
- // if NFC failed for reasons other than getting these details wrong
39
- @property (nonatomic, copy) NSString *passportNumberForNFC;
40
-
41
- @property (nonatomic, strong) NSDate *dateOfBirth;
42
-
43
- @property (nonatomic, strong) NSDate *dateOfExpiry;
44
-
45
- @property (nonatomic, strong) NSMutableArray<NSDictionary *> *detectedBarcodes;
46
-
47
- // JPEG compression quality 0-100
48
- @property (nonatomic, assign) NSUInteger quality;
49
-
50
-
51
- @end
52
-
53
-
54
- @implementation ALNFCScanViewController
55
-
56
- - (instancetype)initWithLicensekey:(NSString *)licensekey
57
- configuration:(NSDictionary *)anylineConfig
58
- uiConfig:(ALJSONUIConfiguration *)uiConfig
59
- finished:(ALPluginCallback)callback {
60
- if (self = [super init]) {
61
- _licenseKey = licensekey;
62
- _callback = callback;
63
- _config = anylineConfig;
64
- _uiConfig = uiConfig;
65
-
66
- self.quality = 90;
67
- }
68
- return self;
69
- }
70
-
71
- - (void)viewDidLoad {
72
- [super viewDidLoad];
73
-
74
- // NOTE: NFCDetector can throw an exception if the AnylineSDK isn't initialized
75
- // first as it will check the scope value of the license.
76
- //
77
- // If already initialized, happily move along. Otherwise, make a license key
78
- // check here.
79
- NSError *error;
80
- BOOL isInitialized = [ALLicenseUtil sharedInstance].isLicenseValid;
81
- if (!isInitialized) {
82
- [AnylineSDK setupWithLicenseKey:self.licenseKey cacheConfig:nil wrapperConfig:wrapperConfig error:&error];
83
- if ([self showErrorAlertIfNeeded:error]) {
84
- return;
85
- }
86
- }
87
-
88
- if (@available(iOS 13.0, *)) {
89
- self.nfcDetector = [self.class getNFCDetectorWithDelegate:self error:&error];
90
- } else {
91
- error = [ALPluginHelper errorWithMessage:@"iOS 13.0 or newer is required to scan with MRZ / NFC."];
92
- }
93
-
94
- if ([self showErrorAlertIfNeeded:error]) {
95
- return;
96
- }
97
-
98
- [self.view addSubview:self.scanView];
99
-
100
- self.resultDict = [[NSMutableDictionary alloc] init];
101
- self.detectedBarcodes = [NSMutableArray array];
102
-
103
- self.scanView = [ALScanViewFactory withJSONDictionary:self.config delegate:self error:&error];
104
- self.scanView.delegate = self;
105
-
106
- [self configureMRZPlugin];
107
-
108
- if ([self showErrorAlertIfNeeded:error]) {
109
- return;
110
- }
111
-
112
- self.mrzScanViewPlugin = (ALScanViewPlugin *)self.scanView.viewPlugin;
113
-
114
- self.scanView.supportedNativeBarcodeFormats = self.uiConfig.nativeBarcodeFormats;
115
- self.scanView.delegate = self;
116
- self.detectedBarcodes = [NSMutableArray array];
117
-
118
- [self.view addSubview:self.scanView];
119
-
120
- self.scanView.translatesAutoresizingMaskIntoConstraints = false;
121
- [self.scanView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
122
- [self.scanView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
123
- [self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor].active = YES;
124
- [self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
125
-
126
- [self.scanView startCamera];
127
-
128
- [self setupHintView];
129
-
130
- self.doneButton = [ALPluginHelper createButtonForViewController:self config:self.uiConfig];
131
- }
132
-
133
- - (void)viewDidAppear:(BOOL)animated {
134
- [super viewDidAppear:animated];
135
-
136
- NSError *error;
137
- [self startMRZScanning:&error];
138
- [self showErrorAlertIfNeeded:error];
139
- }
140
-
141
- - (void)viewDidDisappear:(BOOL)animated {
142
- [self stopMRZScanning];
143
- [super viewDidDisappear:animated];
144
- }
145
-
146
- - (void)startMRZScanning:(NSError **)error {
147
- [self.mrzScanViewPlugin startWithError:error];
148
- self.hintView.hidden = NO;
149
- }
150
-
151
- - (void)stopMRZScanning {
152
- [self.mrzScanViewPlugin stop];
153
- self.hintView.hidden = YES;
154
- }
155
-
156
- - (void)configureMRZPlugin {
157
-
158
- ALScanViewPlugin *scanViewPlugin = (ALScanViewPlugin *)self.scanView.viewPlugin;
159
- if (![scanViewPlugin isKindOfClass:ALScanViewPlugin.class]) {
160
- return;
161
- }
162
-
163
- ALCutoutConfig *cutoutConfig = scanViewPlugin.scanViewPluginConfig.cutoutConfig;
164
- ALScanFeedbackConfig *scanFeedbackConfig = scanViewPlugin.scanViewPluginConfig.scanFeedbackConfig;
165
-
166
- ALPluginConfig *pluginConfig = scanViewPlugin.scanPlugin.pluginConfig;
167
- ALMrzConfig *mrzConfig = pluginConfig.mrzConfig;
168
-
169
- // a bit lengthy but this is how you properly change the config (mrzFieldScanOptions and mrzMinFieldConfidences)
170
- // taking into account the readonly config fields
171
- mrzConfig.mrzFieldScanOptions = [[ALMrzFieldScanOptions alloc] init];
172
-
173
- mrzConfig.mrzFieldScanOptions.vizAddress = ALMrzScanOption.mrzScanOptionDefault;
174
- mrzConfig.mrzFieldScanOptions.vizDateOfIssue = ALMrzScanOption.mrzScanOptionDefault;
175
- mrzConfig.mrzFieldScanOptions.vizSurname = ALMrzScanOption.mrzScanOptionDefault;
176
- mrzConfig.mrzFieldScanOptions.vizGivenNames = ALMrzScanOption.mrzScanOptionDefault;
177
- mrzConfig.mrzFieldScanOptions.vizDateOfBirth = ALMrzScanOption.mrzScanOptionDefault;
178
- mrzConfig.mrzFieldScanOptions.vizDateOfExpiry = ALMrzScanOption.mrzScanOptionDefault;
179
-
180
- mrzConfig.mrzMinFieldConfidences = [[ALMrzMinFieldConfidences alloc] init];
181
- mrzConfig.mrzMinFieldConfidences.documentNumber = @(90);
182
- mrzConfig.mrzMinFieldConfidences.dateOfBirth = @(90);
183
- mrzConfig.mrzMinFieldConfidences.dateOfExpiry = @(90);
184
-
185
- NSError *error;
186
-
187
- ALViewPluginConfig *scanViewPluginConfig = scanViewPlugin.scanViewPluginConfig;
188
- [self.scanView setViewPluginConfig:scanViewPluginConfig error:&error];
189
-
190
- // the delegate binding was lost when you recreated the ScanPlugin it so you have to bring it back here
191
- scanViewPlugin = (ALScanViewPlugin *)self.scanView.viewPlugin;
192
- scanViewPlugin.scanPlugin.delegate = self;
193
- }
194
-
195
- // MARK: - ALIDPluginDelegate
196
-
197
- - (void)scanPlugin:(ALScanPlugin *)scanPlugin resultReceived:(ALScanResult *)scanResult {
198
-
199
- CGFloat compressionQuality = self.quality / 100.0f;
200
-
201
- // ACO just a failsafe for when cancelOnResult is not true
202
- [self stopMRZScanning];
203
-
204
- self.resultDict = [NSMutableDictionary dictionaryWithDictionary:scanResult.resultDictionary];
205
-
206
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.croppedImage
207
- compressionQuality:compressionQuality];
208
- self.resultDict[@"imagePath"] = imagePath;
209
-
210
- imagePath = [ALPluginHelper saveImageToFileSystem:scanResult.fullSizeImage
211
- compressionQuality:compressionQuality];
212
-
213
- self.resultDict[@"fullImagePath"] = imagePath;
214
-
215
- ALMrzResult *MRZResult = scanResult.pluginResult.mrzResult;
216
- NSString *passportNumber = [MRZResult.documentNumber stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
217
-
218
- self.dateOfBirth = [ALPluginHelper formattedStringToDate:MRZResult.dateOfBirthObject];
219
-
220
- self.dateOfExpiry = [ALPluginHelper formattedStringToDate:MRZResult.dateOfExpiryObject];
221
-
222
- NSMutableString *passportNumberForNFC = [passportNumber mutableCopy];
223
- NSRange passportNumberRange = [MRZResult.mrzString rangeOfString:passportNumber];
224
- if (passportNumberRange.location != NSNotFound) {
225
- if ([MRZResult.mrzString characterAtIndex:NSMaxRange(passportNumberRange)] == '<') {
226
- [passportNumberForNFC appendString:@"<"];
227
- }
228
- }
229
-
230
- self.passportNumberForNFC = passportNumberForNFC;
231
-
232
- [self.nfcDetector startNfcDetectionWithPassportNumber:self.passportNumberForNFC
233
- dateOfBirth:self.dateOfBirth
234
- expirationDate:self.dateOfExpiry];
235
- }
236
-
237
- - (void)handleResult:(id _Nullable)resultObj {
238
-
239
- NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithDictionary:resultObj];
240
- if (self.detectedBarcodes.count) {
241
- resultDictionary[@"nativeBarcodesDetected"] = self.detectedBarcodes;
242
- }
243
-
244
- NSObject<ALViewPluginBase> *scanViewPluginBase = self.scanView.viewPlugin;
245
- if ([scanViewPluginBase isKindOfClass:ALScanViewPlugin.class]) {
246
- ALScanViewPlugin *scanViewPlugin = (ALScanViewPlugin *)scanViewPluginBase;
247
- BOOL cancelOnResult = scanViewPlugin.scanPlugin.pluginConfig.cancelOnResult;
248
- if (cancelOnResult) {
249
- [self dismissViewControllerAnimated:YES completion:nil];
250
- }
251
- } else if ([scanViewPluginBase isKindOfClass:ALViewPluginComposite.class]) {
252
- // for composites, the cancelOnResult values for each child don't matter
253
- [self dismissViewControllerAnimated:YES completion:nil];
254
- }
255
- self.callback(resultDictionary, nil);
256
- }
257
-
258
- - (void)doneButtonPressed:(id)sender {
259
- [self stopMRZScanning];
260
-
261
- __weak __block typeof(self) weakSelf = self;
262
- [self dismissViewControllerAnimated:YES completion:^{
263
- weakSelf.callback(nil, @"Canceled");
264
- }];
265
- }
266
-
267
- // MARK: - ALNFCDetectorDelegate
268
-
269
- - (void)nfcSucceededWithResult:(ALNFCResult * _Nonnull)nfcResult API_AVAILABLE(ios(13.0)) {
270
-
271
- // DataGroup1
272
- NSMutableDictionary *dictResultDataGroup1 = [[NSMutableDictionary alloc] init];
273
-
274
-
275
- [dictResultDataGroup1 setValue:[ALPluginHelper stringForDate:nfcResult.dataGroup1.dateOfBirth]
276
- forKey:@"dateOfBirth"];
277
- [dictResultDataGroup1 setValue:[ALPluginHelper stringForDate:nfcResult.dataGroup1.dateOfExpiry]
278
- forKey:@"dateOfExpiry"];
279
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.documentNumber forKey:@"documentNumber"];
280
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.documentType forKey:@"documentType"];
281
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.firstName forKey:@"firstName"];
282
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.gender forKey:@"gender"];
283
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.issuingStateCode forKey:@"issuingStateCode"];
284
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.lastName forKey:@"lastName"];
285
- [dictResultDataGroup1 setValue:nfcResult.dataGroup1.nationality forKey:@"nationality"];
286
-
287
- [self.resultDict setObject:dictResultDataGroup1 forKey:@"dataGroup1"];
288
-
289
- // DataGroup2
290
- // ACO: we don't put the path into a separate 'dataGroup' category for the wrapper
291
- NSString *imagePath = [ALPluginHelper saveImageToFileSystem:nfcResult.dataGroup2.faceImage
292
- compressionQuality:self.quality / (CGFloat)100.0f];
293
- if (imagePath) {
294
- [self.resultDict setValue:imagePath forKey:@"imagePath"];
295
- }
296
-
297
- // SOD (Passport metadata)
298
- NSMutableDictionary *dictResultSOD = [[NSMutableDictionary alloc] init];
299
-
300
- [dictResultSOD setValue:nfcResult.sod.issuerCertificationAuthority forKey:@"issuerCertificationAuthority"];
301
- [dictResultSOD setValue:nfcResult.sod.issuerCountry forKey:@"issuerCountry"];
302
- [dictResultSOD setValue:nfcResult.sod.issuerOrganization forKey:@"issuerOrganization"];
303
- [dictResultSOD setValue:nfcResult.sod.issuerOrganizationalUnit forKey:@"issuerOrganizationalUnit"];
304
- [dictResultSOD setValue:nfcResult.sod.ldsHashAlgorithm forKey:@"ldsHashAlgorithm"];
305
-
306
- // ACO need to disable this because AppStoreConnect produces a warning with this enabled:
307
- // https://anyline.atlassian.net/browse/SDKY-1509?focusedCommentId=71554
308
- // [dictResultSOB setValue:nfcResult.sod.signatureAlgorithm forKey:@"signatureAlgorithm"];
309
-
310
- [dictResultSOD setValue:nfcResult.sod.validFromString forKey:@"validFromString"];
311
- [dictResultSOD setValue:nfcResult.sod.validUntilString forKey:@"validUntilString"];
312
-
313
- [self.resultDict setObject:dictResultSOD forKey:@"sod"];
314
-
315
- __weak __block typeof(self) weakSelf = self;
316
- dispatch_async(dispatch_get_main_queue(), ^{
317
- [weakSelf handleResult:weakSelf.resultDict];
318
- });
319
- }
320
-
321
- - (void)nfcFailedWithError:(NSError * _Nonnull)error {
322
- dispatch_async(dispatch_get_main_queue(), ^{
323
- if (error.code == ALNFCTagErrorNFCNotSupported) {
324
- [self showAlertWithTitle:@"NFC Not Supported"
325
- message:@"NFC passport reading is not supported on this device."];
326
- }
327
- if (error.code == ALNFCTagErrorResponseError || // MRZ key was likely wrong
328
- error.code == ALNFCTagErrorUnexpectedError) {
329
- // can mean the user pressed the 'Cancel' button while scanning, or the phone lost the
330
- // connection with the NFC chip because it was moved
331
- [self startMRZScanning:nil]; //run the MRZ scanner so we can try again.
332
- } else {
333
- // the MRZ details are correct, but something else went wrong. We can try reading
334
- // the NFC chip again without rescanning the MRZ.
335
- __weak __block typeof(self) weakSelf = self;
336
- dispatch_async(dispatch_get_main_queue(), ^{
337
- [weakSelf.nfcDetector startNfcDetectionWithPassportNumber:weakSelf.passportNumberForNFC
338
- dateOfBirth:weakSelf.dateOfBirth
339
- expirationDate:weakSelf.dateOfExpiry];
340
- });
341
- }
342
- });
343
- }
344
-
345
- // MARK: - ALScanViewDelegate
346
-
347
- - (void)scanView:(ALScanView *)scanView updatedCutoutWithPluginID:(NSString *)pluginID
348
- frame:(CGRect)frame {
349
-
350
- if (CGRectIsEmpty(frame)) {
351
- return;
352
- }
353
-
354
- self.hintView.hidden = NO;
355
-
356
- CGFloat xOffset = self.uiConfig.labelXPositionOffset;
357
- CGFloat yOffset = self.uiConfig.labelYPositionOffset;
358
-
359
- // takes into account that frame reported for a cutout is in relation to
360
- // its scan view's coordinate system
361
- yOffset += [self.scanView convertRect:frame toView:self.scanView.superview].origin.y;
362
-
363
- self.labelHorizontalOffsetConstraint.constant = xOffset;
364
- self.labelVerticalOffsetConstraint.constant = yOffset;
365
- }
366
-
367
- - (void)scanView:(ALScanView *)scanView didReceiveNativeBarcodeResult:(ALScanResult *)scanResult {
368
- // for this implementation we just take the last detected (we can show a list of it)
369
- [self.detectedBarcodes removeAllObjects];
370
- [self.detectedBarcodes addObject:scanResult.resultDictionary];
371
- }
372
-
373
-
374
- // MARK: - ALNFCDetector
375
-
376
- + (ALNFCDetector * _Nullable)getNFCDetectorWithDelegate:(id<ALNFCDetectorDelegate> _Nonnull)delegate
377
- error:(NSError * _Nullable * _Nullable)error API_AVAILABLE(ios(13.0)) {
378
- ALNFCDetector *NFCDetector;
379
- if (![ALNFCDetector readingAvailable]) {
380
- if (error) {
381
- *error = [ALPluginHelper errorWithMessage:@"NFC is not available for this device."];
382
- }
383
- return nil;
384
- }
385
- NFCDetector = [[ALNFCDetector alloc] initWithDelegate:delegate error:error];
386
- if (!NFCDetector) {
387
- return nil;
388
- }
389
- return NFCDetector;
390
- }
391
-
392
- // MARK: - Alerts
393
-
394
- - (void)showAlertWithTitle:(NSString *)title message:(NSString *)message {
395
- [ALPluginHelper showErrorAlertWithTitle:title message:message
396
- presentingViewController:self.navigationController];
397
- }
398
-
399
- - (BOOL)showErrorAlertIfNeeded:(NSError *)error {
400
- return [ALPluginHelper showErrorAlertIfNeeded:error pluginCallback:self.callback];
401
- }
402
-
403
- // MARK: - User Interface
404
-
405
- - (void)setupHintView {
406
-
407
- UIView *hintView = [[UIView alloc] initWithFrame:CGRectZero];
408
- hintView.layer.cornerRadius = 8;
409
- hintView.layer.masksToBounds = true;
410
- hintView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
411
-
412
- hintView.translatesAutoresizingMaskIntoConstraints = NO;
413
- [self.view addSubview:hintView];
414
-
415
- self.labelHorizontalOffsetConstraint = [hintView.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor constant:0];
416
-
417
- // at 0, the bottom of the label (container) should be touching the cutout top when the updatedCutoutRect report
418
- // is made
419
- self.labelVerticalOffsetConstraint = [hintView.bottomAnchor constraintEqualToAnchor:self.view.topAnchor constant:0];
420
-
421
- self.labelHorizontalOffsetConstraint.active = YES;
422
- self.labelVerticalOffsetConstraint.active = YES;
423
-
424
- UILabel *hintViewLabel = [[UILabel alloc] initWithFrame:CGRectZero];
425
-
426
- hintViewLabel.text = @"Scan MRZ";
427
- if (self.uiConfig.labelText.length) {
428
- hintViewLabel.text = self.uiConfig.labelText;
429
- }
430
-
431
- hintViewLabel.font = [UIFont fontWithName:@"HelveticaNeue"
432
- size:self.uiConfig.labelSize];
433
- hintViewLabel.textColor = self.uiConfig.labelColor;
434
- hintViewLabel.textAlignment = NSTextAlignmentCenter;
435
- hintViewLabel.translatesAutoresizingMaskIntoConstraints = NO;
436
- [hintViewLabel sizeToFit];
437
- [hintView addSubview:hintViewLabel];
438
-
439
- [hintViewLabel.centerXAnchor constraintEqualToAnchor:hintView.centerXAnchor].active = YES;
440
- [hintViewLabel.centerYAnchor constraintEqualToAnchor:hintView.centerYAnchor].active = YES;
441
-
442
- NSLayoutConstraint *cnst = [hintView.widthAnchor constraintGreaterThanOrEqualToAnchor:hintViewLabel.widthAnchor
443
- constant:20];
444
- cnst.active = YES;
445
- cnst = [hintView.heightAnchor constraintEqualToAnchor:hintViewLabel.heightAnchor constant:20];
446
- cnst.active = YES;
447
-
448
- self.hintView = hintView;
449
- self.hintViewLabel = hintViewLabel;
450
- }
451
-
452
- @end