Browse Source

k线滑动与放大缩小

main
lihuilin 1 month ago
parent
commit
aa79e41bf7
  1. 4
      HC.xcodeproj/project.pbxproj
  2. 5
      HC.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  3. 16
      HC.xcodeproj/project.xcworkspace/xcuserdata/huilinli.xcuserdatad/WorkspaceSettings.xcsettings
  4. 72
      HC.xcodeproj/xcuserdata/huilinli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  5. 2
      HC/AppDelegate.h
  6. 7
      HC/AppDelegate.m
  7. 21
      HC/Assets.xcassets/banner1.imageset/Contents.json
  8. BIN
      HC/Assets.xcassets/banner1.imageset/banner1.jpg
  9. 21
      HC/Assets.xcassets/banner2.imageset/Contents.json
  10. BIN
      HC/Assets.xcassets/banner2.imageset/banner2.jpg
  11. 21
      HC/Assets.xcassets/email.imageset/Contents.json
  12. BIN
      HC/Assets.xcassets/email.imageset/email.jpg
  13. 21
      HC/Assets.xcassets/hqz.imageset/Contents.json
  14. BIN
      HC/Assets.xcassets/hqz.imageset/hqz.jpg
  15. 20
      HC/Assets.xcassets/image.imageset/Contents.json
  16. BIN
      HC/Assets.xcassets/logo.imageset/20251117-225344.jpg
  17. 21
      HC/Assets.xcassets/logo.imageset/Contents.json
  18. BIN
      HC/Assets.xcassets/logo.jpg
  19. 21
      HC/Assets.xcassets/singapore_flag.imageset/Contents.json
  20. BIN
      HC/Assets.xcassets/singapore_flag.imageset/singapore_flag.jpg
  21. 16
      HC/CNViewController.h
  22. 12
      HC/CNViewController.m
  23. 16
      HC/ChartViewController.h
  24. 592
      HC/ChartViewController.m
  25. 19
      HC/CommonTabBar.h
  26. 94
      HC/CommonTabBar.m
  27. 18
      HC/CountryModel.h
  28. 20
      HC/CountryModel.m
  29. 45
      HC/HomeViewController.h
  30. 634
      HC/HomeViewController.m
  31. 16
      HC/MLXYViewController.h
  32. 442
      HC/MLXYViewController.m
  33. 18
      HC/MyViewController.h
  34. 390
      HC/MyViewController.m
  35. 16
      HC/QuotationViewController.h
  36. 258
      HC/QuotationViewController.m
  37. 22
      HC/SceneDelegate.m
  38. 36
      HC/StockKLineModel.h
  39. 21
      HC/StockKLineModel.m
  40. 3
      HC/ViewController.h
  41. 279
      HC/ViewController.m

4
HC.xcodeproj/project.pbxproj

@ -11,7 +11,7 @@
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
38BE1CFC2ECC0F28004B805B /* Exceptions for "HC" folder in "HC" target */ = {
3895388C2ED53BDF004AECEA /* Exceptions for "HC" folder in "HC" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
Info.plist,
@ -24,7 +24,7 @@
38BE1CE42ECC0F27004B805B /* HC */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
38BE1CFC2ECC0F28004B805B /* Exceptions for "HC" folder in "HC" target */,
3895388C2ED53BDF004AECEA /* Exceptions for "HC" folder in "HC" target */,
);
path = HC;
sourceTree = "<group>";

5
HC.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
</plist>

16
HC.xcodeproj/project.xcworkspace/xcuserdata/huilinli.xcuserdatad/WorkspaceSettings.xcsettings

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildLocationStyle</key>
<string>UseAppPreferences</string>
<key>CompilationCachingSetting</key>
<string>Default</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>ShowSharedSchemesAutomaticallyEnabled</key>
<true/>
</dict>
</plist>

72
HC.xcodeproj/xcuserdata/huilinli.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "E5AAA2DB-88F5-499D-B52C-3BC768440386"
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "C0178EEE-BAE9-481C-89D7-E23AE1320BBC"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "HC/ViewController.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "206"
endingLineNumber = "206"
landmarkName = "-setupConstraints"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "E0BA58D2-B977-4CD8-A825-57A0428B1AEA"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "HC/HomeViewController.h"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "12"
endingLineNumber = "12"
landmarkName = "HomeViewController"
landmarkType = "2">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "D5AC1EC8-1AFB-409C-AECD-7665735E5E22"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "HC/HomeViewController.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "399"
endingLineNumber = "399"
landmarkName = "-setupConstraints"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
<BreakpointContent
uuid = "F6BBF337-745E-4379-B25C-7E9CA910F97C"
shouldBeEnabled = "No"
ignoreCount = "0"
continueAfterRunningActions = "No"
filePath = "HC/HomeViewController.m"
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "63"
endingLineNumber = "63"
landmarkName = "-setupSubviews"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

2
HC/AppDelegate.h

@ -11,7 +11,7 @@
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (readonly, strong) NSPersistentContainer *persistentContainer;
@property (strong, nonatomic) UIWindow *window;
- (void)saveContext;

7
HC/AppDelegate.m

@ -6,6 +6,8 @@
//
#import "AppDelegate.h"
#import "ViewController.h"
#import "ChartViewController.h"
@interface AppDelegate ()
@ -15,11 +17,12 @@
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
#if DEBUG
[[NSBundle bundleWithPath:@"/Applications/InjectionIII.app/Contents/Resources/iOSInjection.bundle"] load];
#endif
return YES;
}
#pragma mark - UISceneSession lifecycle

21
HC/Assets.xcassets/banner1.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "banner1.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/banner1.imageset/banner1.jpg

After

Width: 1161  |  Height: 378  |  Size: 21 KiB

21
HC/Assets.xcassets/banner2.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "banner2.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/banner2.imageset/banner2.jpg

After

Width: 1161  |  Height: 378  |  Size: 21 KiB

21
HC/Assets.xcassets/email.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "email.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/email.imageset/email.jpg

After

Width: 75  |  Height: 55  |  Size: 1.4 KiB

21
HC/Assets.xcassets/hqz.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "hqz.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/hqz.imageset/hqz.jpg

After

Width: 602  |  Height: 582  |  Size: 258 KiB

20
HC/Assets.xcassets/image.imageset/Contents.json

@ -0,0 +1,20 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/logo.imageset/20251117-225344.jpg

After

Width: 143  |  Height: 142  |  Size: 3.1 KiB

21
HC/Assets.xcassets/logo.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "20251117-225344.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/logo.jpg

After

Width: 143  |  Height: 142  |  Size: 3.1 KiB

21
HC/Assets.xcassets/singapore_flag.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "singapore_flag.jpg",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
HC/Assets.xcassets/singapore_flag.imageset/singapore_flag.jpg

After

Width: 146  |  Height: 87  |  Size: 2.1 KiB

16
HC/CNViewController.h

@ -0,0 +1,16 @@
//
// CNViewController.h
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface CNViewController : UIViewController
@end
NS_ASSUME_NONNULL_END

12
HC/CNViewController.m

@ -0,0 +1,12 @@
//
// CNViewController.m
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import "CNViewController.h"
@implementation CNViewController
@end

16
HC/ChartViewController.h

@ -0,0 +1,16 @@
//
// ChartViewController.h
// HC
//
// Created by huilinLi on 2025/11/27.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface ChartViewController : UIViewController
@end
NS_ASSUME_NONNULL_END

592
HC/ChartViewController.m

@ -0,0 +1,592 @@
// ChartViewController.m
// HC
//
// Created by huilinLi on 2025/11/27.
//
#import "ChartViewController.h"
#import "StockKLineModel.h"
@interface ChartViewController ()
// 上方卡片容器
@property (nonatomic, strong) UIView *cardContainer;
// k线选择项容器
@property (nonatomic, strong) UIView *kSelectContainer;
// K线图表容器
@property (nonatomic, strong) UIView *kLineContainer;
// K线图表滚动视图
@property (nonatomic, strong) UIScrollView *kLineScrollView;
// K线数据
@property (nonatomic, strong) NSArray *kLineData;
// 价格刻度标签
@property (nonatomic, strong) NSArray *priceLabels;
// 日期刻度标签
@property (nonatomic, strong) NSArray *dateLabels;
// 默认展示的K线数量
@property (nonatomic, assign) NSInteger visibleKLineCount;
@end
@implementation ChartViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
self.visibleKLineCount = 40;
[self generateMockData];
[self setupSubviews];
[self setupConstraints];
dispatch_async(dispatch_get_main_queue(), ^{
[self drawKLineChart];
if (self.kLineScrollView.contentSize.width > self.kLineScrollView.bounds.size.width) {
CGPoint offset = CGPointMake(self.kLineScrollView.contentSize.width - self.kLineScrollView.bounds.size.width, 0);
[self.kLineScrollView setContentOffset:offset animated:NO];
}
});
}
#pragma mark - UI Setup
-(void) setupSubviews{
// 卡片容器
_cardContainer = [[UIView alloc] init];
_cardContainer.backgroundColor = [UIColor colorWithRed:26.0/255.0
green:26.0/255.0
blue:2.0/255.0
alpha:1.0];
_cardContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_cardContainer];
UILabel *cardLabel1 = [[UILabel alloc] init];
cardLabel1.text = @"1617.060";
cardLabel1.textColor = [UIColor redColor];
cardLabel1.font = [UIFont systemFontOfSize:15];
cardLabel1.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabel1];
UILabel *cardLabel2 = [[UILabel alloc] init];
cardLabel2.text = @"-7.470";
cardLabel2.textColor = [UIColor redColor];
cardLabel2.font = [UIFont systemFontOfSize:8];
cardLabel2.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabel2];
UILabel *cardLabel3 = [[UILabel alloc] init];
cardLabel3.text = @"-0.461%";
cardLabel3.textColor = [UIColor redColor];
cardLabel3.font = [UIFont systemFontOfSize:8];
cardLabel3.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabel3];
[NSLayoutConstraint activateConstraints:@[
[cardLabel1.topAnchor constraintEqualToAnchor:_cardContainer.topAnchor constant:25],
[cardLabel1.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:10],
[cardLabel2.topAnchor constraintEqualToAnchor:_cardContainer.topAnchor constant:50],
[cardLabel2.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant: 8],
[cardLabel3.topAnchor constraintEqualToAnchor:_cardContainer.topAnchor constant:50],
[cardLabel3.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant: 45]
]];
UILabel *cardLabelHeight = [[UILabel alloc] init];
cardLabelHeight.text = @"高";
cardLabelHeight.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
cardLabelHeight.font = [UIFont systemFontOfSize:15];
cardLabelHeight.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabelHeight];
UILabel *cardLabelStart = [[UILabel alloc] init];
cardLabelStart.text = @"开";
cardLabelStart.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
cardLabelStart.font = [UIFont systemFontOfSize:15];
cardLabelStart.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabelStart];
UILabel *cardLabelVolume = [[UILabel alloc] init];
cardLabelVolume.text = @"量";
cardLabelVolume.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
cardLabelVolume.font = [UIFont systemFontOfSize:15];
cardLabelVolume.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabelVolume];
UILabel *cardLabelLow = [[UILabel alloc] init];
cardLabelLow.text = @"低";
cardLabelLow.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
cardLabelLow.font = [UIFont systemFontOfSize:15];
cardLabelLow.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabelLow];
UILabel *cardLabelChange = [[UILabel alloc] init];
cardLabelChange.text = @"换";
cardLabelChange.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
cardLabelChange.font = [UIFont systemFontOfSize:15];
cardLabelChange.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabelChange];
UILabel *cardLabelQuota = [[UILabel alloc] init];
cardLabelQuota.text = @"额";
cardLabelQuota.textColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
cardLabelQuota.font = [UIFont systemFontOfSize:15];
cardLabelQuota.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardLabelQuota];
UILabel *cardNumHeight = [[UILabel alloc] init];
cardNumHeight.text = @"1617.260";
cardNumHeight.textColor = [UIColor redColor];
cardNumHeight.font = [UIFont systemFontOfSize:12];
cardNumHeight.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardNumHeight];
UILabel *cardNumStart = [[UILabel alloc] init];
cardNumStart.text = @"1616.750";
cardNumStart.textColor = [UIColor redColor];
cardNumStart.font = [UIFont systemFontOfSize:12];
cardNumStart.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardNumStart];
UILabel *cardNumVolume = [[UILabel alloc] init];
cardNumVolume.text = @"1.511亿";
cardNumVolume.textColor = [UIColor whiteColor];
cardNumVolume.font = [UIFont systemFontOfSize:12];
cardNumVolume.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardNumVolume];
UILabel *cardNumLow = [[UILabel alloc] init];
cardNumLow.text = @"1608.850";
cardNumLow.textColor = [UIColor whiteColor];
cardNumLow.font = [UIFont systemFontOfSize:12];
cardNumLow.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardNumLow];
UILabel *cardNumChange = [[UILabel alloc] init];
cardNumChange.text = @"--";
cardNumChange.textColor = [UIColor whiteColor];
cardNumChange.font = [UIFont systemFontOfSize:12];
cardNumChange.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardNumChange];
UILabel *cardNumQuota = [[UILabel alloc] init];
cardNumQuota.text = @"--";
cardNumQuota.textColor = [UIColor whiteColor];
cardNumQuota.font = [UIFont systemFontOfSize:12];
cardNumQuota.translatesAutoresizingMaskIntoConstraints = NO;
[_cardContainer addSubview:cardNumQuota];
[NSLayoutConstraint activateConstraints:@[
[cardLabelHeight.bottomAnchor constraintEqualToAnchor:_cardContainer.bottomAnchor constant:-75],
[cardLabelStart.bottomAnchor constraintEqualToAnchor:cardLabelHeight.bottomAnchor],
[cardLabelVolume.bottomAnchor constraintEqualToAnchor:cardLabelHeight.bottomAnchor],
[cardLabelLow.topAnchor constraintEqualToAnchor:_cardContainer.bottomAnchor constant:-50],
[cardLabelLow.leadingAnchor constraintEqualToAnchor:cardLabelHeight.leadingAnchor],
[cardLabelChange.topAnchor constraintEqualToAnchor:_cardContainer.bottomAnchor constant:-50],
[cardLabelChange.leadingAnchor constraintEqualToAnchor:cardLabelStart.leadingAnchor],
[cardLabelQuota.topAnchor constraintEqualToAnchor:_cardContainer.bottomAnchor constant:-50],
[cardLabelQuota.leadingAnchor constraintEqualToAnchor:cardLabelVolume.leadingAnchor],
[cardNumHeight.bottomAnchor constraintEqualToAnchor:_cardContainer.topAnchor constant:45],
[cardNumHeight.leadingAnchor constraintEqualToAnchor:cardLabelHeight.leadingAnchor],
[cardNumStart.bottomAnchor constraintEqualToAnchor:cardNumHeight.bottomAnchor],
[cardNumStart.leadingAnchor constraintEqualToAnchor:cardLabelStart.leadingAnchor],
[cardNumVolume.bottomAnchor constraintEqualToAnchor:cardNumHeight.bottomAnchor],
[cardNumVolume.leadingAnchor constraintEqualToAnchor:cardLabelVolume.leadingAnchor],
[cardNumLow.bottomAnchor constraintEqualToAnchor:_cardContainer.bottomAnchor constant:-10],
[cardNumLow.leadingAnchor constraintEqualToAnchor:cardLabelLow.leadingAnchor],
[cardNumChange.bottomAnchor constraintEqualToAnchor:cardNumLow.bottomAnchor],
[cardNumChange.leadingAnchor constraintEqualToAnchor:cardLabelChange.leadingAnchor],
[cardNumQuota.bottomAnchor constraintEqualToAnchor:cardNumLow.bottomAnchor],
[cardNumQuota.leadingAnchor constraintEqualToAnchor:cardLabelVolume.leadingAnchor]
]];
[NSLayoutConstraint constraintWithItem:cardLabelHeight
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:_cardContainer
attribute:NSLayoutAttributeTrailing
multiplier:0.25
constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:cardLabelStart
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:_cardContainer
attribute:NSLayoutAttributeTrailing
multiplier:0.5
constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:cardLabelVolume
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:_cardContainer
attribute:NSLayoutAttributeTrailing
multiplier:0.75
constant:0].active = YES;
// K线选择项容器
_kSelectContainer = [[UIView alloc] init];
_kSelectContainer.backgroundColor = [UIColor colorWithRed:26.0/255.0
green:26.0/255.0
blue:2.0/255.0
alpha:1.0];
_kSelectContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_kSelectContainer];
[self addKSelectOptions];
// K线图表容器
self.kLineContainer = [[UIView alloc] init];
self.kLineContainer.backgroundColor = [UIColor colorWithRed:26.0/255.0 green:26.0/255.0 blue:26.0/255.0 alpha:1.0];
self.kLineContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.kLineContainer];
// K线图表滚动视图
self.kLineScrollView = [[UIScrollView alloc] init];
self.kLineScrollView.backgroundColor = [UIColor clearColor];
self.kLineScrollView.showsHorizontalScrollIndicator = NO;
self.kLineScrollView.userInteractionEnabled = YES;
self.kLineScrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.kLineContainer addSubview:self.kLineScrollView];
CGFloat priceLabelAreaWidth = 50.0;
// 滚动视图的约束
[NSLayoutConstraint activateConstraints:@[
[self.kLineScrollView.topAnchor constraintEqualToAnchor:self.kLineContainer.topAnchor],
[self.kLineScrollView.bottomAnchor constraintEqualToAnchor:self.kLineContainer.bottomAnchor],
[self.kLineScrollView.leadingAnchor constraintEqualToAnchor:self.kLineContainer.leadingAnchor constant:priceLabelAreaWidth],
[self.kLineScrollView.trailingAnchor constraintEqualToAnchor:self.kLineContainer.trailingAnchor],
[self.kLineScrollView.heightAnchor constraintEqualToAnchor:self.kLineContainer.heightAnchor]
]];
// 边框
UIView *borderView = [[UIView alloc] init];
borderView.backgroundColor = [UIColor clearColor];
borderView.layer.borderWidth = 1;
borderView.layer.borderColor = [[UIColor colorWithRed:0.4 green:0.4 blue:0.4 alpha:1.0] CGColor];
borderView.translatesAutoresizingMaskIntoConstraints = NO;
[self.kLineContainer addSubview:borderView];
[NSLayoutConstraint activateConstraints:@[
[borderView.leadingAnchor constraintEqualToAnchor:self.kLineContainer.leadingAnchor],
[borderView.trailingAnchor constraintEqualToAnchor:self.kLineContainer.trailingAnchor],
[borderView.topAnchor constraintEqualToAnchor:self.kLineContainer.topAnchor],
[borderView.bottomAnchor constraintEqualToAnchor:self.kLineContainer.bottomAnchor]
]];
// 动态计算模型数据的价格区间
CGFloat maxPrice = 0;
CGFloat minPrice = CGFLOAT_MAX;
for (id item in self.kLineData) {
if ([item isKindOfClass:[StockKLineModel class]]) {
StockKLineModel *model = (StockKLineModel *)item;
maxPrice = MAX(maxPrice, model.high);
minPrice = MIN(minPrice, model.low);
} else if ([item isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)item;
maxPrice = MAX(maxPrice, [dict[@"high"] floatValue]);
minPrice = MIN(minPrice, [dict[@"low"] floatValue]);
}
}
maxPrice = maxPrice + (maxPrice - minPrice) * 0.1;
minPrice = minPrice - (maxPrice - minPrice) * 0.1;
// 价格刻度
NSMutableArray *priceLabelArr = [NSMutableArray array];
for (NSInteger i = 0; i < 5; i++) {
CGFloat price = maxPrice - (maxPrice - minPrice) / 4 * i;
UILabel *label = [[UILabel alloc] init];
label.text = [NSString stringWithFormat:@"%.1f", price];
label.textColor = [UIColor lightGrayColor];
label.font = [UIFont systemFontOfSize:10];
label.translatesAutoresizingMaskIntoConstraints = NO;
[self.kLineContainer addSubview:label];
[NSLayoutConstraint activateConstraints:@[
[label.leadingAnchor constraintEqualToAnchor:self.kLineContainer.leadingAnchor constant:5],
[label.centerYAnchor constraintEqualToAnchor:self.kLineContainer.centerYAnchor constant:-80 + 40 * i]
]];
[priceLabelArr addObject:label];
}
self.priceLabels = priceLabelArr;
self.dateLabels = @[];
}
- (void)addKSelectOptions {
NSArray *titles = @[@"日k", @"周k", @"月k", @"更多", @"设置"];
UIStackView *stackView = [[UIStackView alloc] init];
stackView.axis = UILayoutConstraintAxisHorizontal;
stackView.distribution = UIStackViewDistributionFillEqually;
stackView.alignment = UIStackViewAlignmentCenter;
stackView.spacing = 5.0;
stackView.translatesAutoresizingMaskIntoConstraints = NO;
for (NSString *title in titles) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:title forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize:14];
[button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
if ([title isEqualToString:@"日k"]) {
[button setTitleColor:[UIColor yellowColor] forState:UIControlStateNormal];
button.layer.borderColor = [[UIColor yellowColor] CGColor];
button.layer.borderWidth = 1.0;
} else {
[button setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
button.layer.borderWidth = 0;
}
button.layer.cornerRadius = 3.0;
button.clipsToBounds = YES;
[stackView addArrangedSubview:button];
}
[_kSelectContainer addSubview:stackView];
[NSLayoutConstraint activateConstraints:@[
[stackView.leadingAnchor constraintEqualToAnchor:_kSelectContainer.leadingAnchor constant:10],
[stackView.trailingAnchor constraintEqualToAnchor:_kSelectContainer.trailingAnchor constant:-10],
[stackView.topAnchor constraintEqualToAnchor:_kSelectContainer.topAnchor constant:5],
[stackView.bottomAnchor constraintEqualToAnchor:_kSelectContainer.bottomAnchor constant:-5]
]];
}
#pragma mark - Constraints
- (void)setupConstraints{
[NSLayoutConstraint activateConstraints:@[
[_cardContainer.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[_cardContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[_cardContainer.widthAnchor constraintEqualToAnchor:self.view.widthAnchor],
[_cardContainer.heightAnchor constraintEqualToConstant:100],
[_kSelectContainer.topAnchor constraintEqualToAnchor:_cardContainer.bottomAnchor constant:5],
[_kSelectContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[_kSelectContainer.widthAnchor constraintEqualToAnchor:self.view.widthAnchor],
[_kSelectContainer.heightAnchor constraintEqualToConstant:40],
[self.kLineContainer.topAnchor constraintEqualToAnchor:self.kSelectContainer.bottomAnchor constant:5],
[self.kLineContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.kLineContainer.widthAnchor constraintEqualToAnchor:self.view.widthAnchor],
[self.kLineContainer.heightAnchor constraintEqualToConstant:200]
]];
}
#pragma mark - KLine Drawing
- (void)drawKLineChart {
// 移除旧的 K 线
for (UIView *subview in self.kLineScrollView.subviews) {
if (![subview isKindOfClass:[UILabel class]]) {
[subview removeFromSuperview];
}
}
CGFloat chartHeight = self.kLineContainer.bounds.size.height;
if (chartHeight == 0) {
chartHeight = 200;
}
// K线宽度计算
CGFloat kLineUnitWidth = 5.0;
CGFloat kLineRatio = 0.8;
CGFloat kLineWidth = kLineUnitWidth * kLineRatio;
CGFloat space = kLineUnitWidth * (1.0 - kLineRatio);
CGFloat totalChartWidth = kLineUnitWidth * self.kLineData.count;
// 设置contentSize
self.kLineScrollView.contentSize = CGSizeMake(totalChartWidth, chartHeight);
// 动态计算价格区间
CGFloat maxPrice = 0;
CGFloat minPrice = CGFLOAT_MAX;
for (id item in self.kLineData) {
if ([item isKindOfClass:[StockKLineModel class]]) {
StockKLineModel *model = (StockKLineModel *)item;
maxPrice = MAX(maxPrice, model.high);
minPrice = MIN(minPrice, model.low);
} else if ([item isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)item;
maxPrice = MAX(maxPrice, [dict[@"high"] floatValue]);
minPrice = MIN(minPrice, [dict[@"low"] floatValue]);
}
}
maxPrice = maxPrice + (maxPrice - minPrice) * 0.1;
minPrice = minPrice - (maxPrice - minPrice) * 0.1;
CGFloat priceRange = maxPrice - minPrice;
// 绘制K线
for (NSInteger i = 0; i < self.kLineData.count; i++) {
CGFloat open = 0, high = 0, low = 0, close = 0;
if ([self.kLineData[i] isKindOfClass:[StockKLineModel class]]) {
StockKLineModel *model = (StockKLineModel *)self.kLineData[i];
open = model.open;
high = model.high;
low = model.low;
close = model.close;
} else if ([self.kLineData[i] isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)self.kLineData[i];
open = [dict[@"open"] floatValue];
high = [dict[@"high"] floatValue];
low = [dict[@"low"] floatValue];
close = [dict[@"close"] floatValue];
}
// 坐标转换
CGFloat yOpen = chartHeight * (maxPrice - open) / priceRange;
CGFloat yHigh = chartHeight * (maxPrice - high) / priceRange;
CGFloat yLow = chartHeight * (maxPrice - low) / priceRange;
CGFloat yClose = chartHeight * (maxPrice - close) / priceRange;
// 计算X坐标
CGFloat xPosition = space/2 + kLineUnitWidth * i;
// 绘制K线实体
UIView *bodyView = [[UIView alloc] init];
bodyView.backgroundColor = (close >= open) ? [UIColor greenColor] : [UIColor redColor];
bodyView.frame = CGRectMake(
xPosition,
MIN(yOpen, yClose),
kLineWidth,
MAX(1.0, fabs(yClose - yOpen))
);
[self.kLineScrollView addSubview:bodyView];
// 绘制影线
UIView *shadowView = [[UIView alloc] init];
shadowView.backgroundColor = bodyView.backgroundColor;
shadowView.frame = CGRectMake(
bodyView.center.x - 0.5,
yHigh,
1,
yLow - yHigh
);
[self.kLineScrollView addSubview:shadowView];
}
// 日期刻度
for (UILabel *label in self.dateLabels) {
[label removeFromSuperview];
}
NSMutableArray *dateLabelArr = [NSMutableArray array];
NSInteger dateInterval = 10;
for (NSInteger i = 0; i < self.kLineData.count; i += dateInterval) {
NSString *dateStr = @"";
if ([self.kLineData[i] isKindOfClass:[StockKLineModel class]]) {
StockKLineModel *model = (StockKLineModel *)self.kLineData[i];
dateStr = model.date;
} else if ([self.kLineData[i] isKindOfClass:[NSDictionary class]]) {
NSDictionary *dict = (NSDictionary *)self.kLineData[i];
dateStr = dict[@"date"];
}
UILabel *label = [[UILabel alloc] init];
label.text = dateStr;
label.textColor = [UIColor lightGrayColor];
label.font = [UIFont systemFontOfSize:10];
label.translatesAutoresizingMaskIntoConstraints = YES;
CGFloat xCenter = kLineUnitWidth * (i + 0.5);
[label sizeToFit];
label.frame = CGRectMake(
xCenter - label.bounds.size.width / 2,
chartHeight - 15,
label.bounds.size.width,
label.bounds.size.height
);
[self.kLineScrollView addSubview:label];
[dateLabelArr addObject:label];
}
self.dateLabels = dateLabelArr;
NSLog(@"ScrollView Bounds Width: %f", self.kLineScrollView.bounds.size.width);
NSLog(@"Content Size Width: %f", self.kLineScrollView.contentSize.width);
if (self.kLineScrollView.contentSize.width <= self.kLineScrollView.bounds.size.width) {
NSLog(@"⚠️ 警告:ContentSize 不够大,无法滑动。");
}
}
#pragma mark - Mock Data
- (void) setupData{
self.kLineData = @[
@{@"date":@"2025/11/18", @"open":@1620.0, @"high":@1643.0, @"low":@1605.0, @"close":@1630.0, @"volume":@2.5},
@{@"date":@"2025/11/19", @"open":@1630.0, @"high":@1635.0, @"low":@1615.0, @"close":@1620.0, @"volume":@2.2},
@{@"date":@"2025/11/20", @"open":@1620.0, @"high":@1628.0, @"low":@1608.0, @"close":@1615.0, @"volume":@1.8},
@{@"date":@"2025/11/21", @"open":@1615.0, @"high":@1625.0, @"low":@1610.0, @"close":@1622.0, @"volume":@2.0},
@{@"date":@"2025/11/22", @"open":@1622.0, @"high":@1630.0, @"low":@1618.0, @"close":@1625.0, @"volume":@2.3},
@{@"date":@"2025/11/25", @"open":@1625.0, @"high":@1632.0, @"low":@1620.0, @"close":@1628.0, @"volume":@1.9},
@{@"date":@"2025/11/26", @"open":@1628.0, @"high":@1635.0, @"low":@1622.0, @"close":@1630.0, @"volume":@2.1},
@{@"date":@"2025/11/27", @"open":@1630.0, @"high":@1638.0, @"low":@1625.0, @"close":@1628.0, @"volume":@2.4},
@{@"date":@"2025/11/28", @"open":@1628.0, @"high":@1632.0, @"low":@1609.0, @"close":@1610.0, @"volume":@2.6},
@{@"date":@"2025/11/29", @"open":@1610.0, @"high":@1620.0, @"low":@1608.0, @"close":@1615.0, @"volume":@1.7}
];
}
- (void)generateMockData {
NSMutableArray *arr = [NSMutableArray array];
CGFloat lastClose = 100.0;
NSLog(@"生成模拟数据中。。。");
// 生成200条数据(减少数量,避免contentSize过大
for (int i = 0; i < 200; i++) {
StockKLineModel *model = [[StockKLineModel alloc] init];
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:-(200 - i) * 24 * 3600];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:@"MM-dd"];
model.date = [fmt stringFromDate:date];
// 价格生成逻辑
CGFloat volatility = lastClose * 0.02;
CGFloat randomChange = ((arc4random() % 100) / 100.0 - 0.5) * 2 * volatility;
model.open = lastClose + ((arc4random() % 100) / 100.0 - 0.5) * volatility * 0.5;
model.close = model.open + randomChange;
CGFloat maxOC = MAX(model.open, model.close);
CGFloat minOC = MIN(model.open, model.close);
model.high = maxOC + (arc4random() % 100) / 100.0 * 1.0;
model.low = minOC - (arc4random() % 100) / 100.0 * 1.0;
// 成交量生成逻辑
CGFloat baseVolume = 1000000.0;
CGFloat randomVolFactor = (arc4random() % 200) / 100.0 + 0.5;
if (fabs(model.close - model.open) / model.open > 0.03) {
randomVolFactor *= 1.5;
}
model.volume = baseVolume * randomVolFactor;
if (model.low < 0) model.low = 0.01;
[arr addObject:model];
lastClose = model.close;
}
NSLog(@"生成模拟数据完毕,共%ld条", arr.count);
self.kLineData = arr;
}
@end

19
HC/CommonTabBar.h

@ -0,0 +1,19 @@
//
// CommonTabBar.h
// HC
//
// Created by huilinLi on 2025/11/25.
//
#import <UIKit/UIKit.h>
@protocol CommonTabBarDelegate <NSObject>
- (void)tabBarDidSelectIndex:(NSInteger)index;
@end
@interface CommonTabBar : UIView
@property (nonatomic, weak) id<CommonTabBarDelegate> delegate;
@property (nonatomic, assign) NSInteger selectedIndex; //
- (instancetype)initWithTabItems:(NSArray<NSDictionary *> *)tabItems;
@end

94
HC/CommonTabBar.m

@ -0,0 +1,94 @@
//
// CommonTabBar.m
// HC
//
// Created by huilinLi on 2025/11/25.
//
#import "CommonTabBar.h"
@interface CommonTabBar ()
@property (nonatomic, strong) NSArray<UIButton *> *tabButtons;
@end
@implementation CommonTabBar
- (instancetype)initWithTabItems:(NSArray<NSDictionary *> *)tabItems {
self = [super init];
if (self) {
self.backgroundColor = [UIColor blackColor];
self.translatesAutoresizingMaskIntoConstraints = NO;
[self setupTabButtonsWithItems:tabItems];
}
return self;
}
- (void)setupTabButtonsWithItems:(NSArray<NSDictionary *> *)tabItems {
NSMutableArray<UIButton *> *buttons = [NSMutableArray array];
for (NSInteger i = 0; i < tabItems.count; i++) {
NSDictionary *item = tabItems[i];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
UIButtonConfiguration *config = [UIButtonConfiguration plainButtonConfiguration];
config.image = [UIImage systemImageNamed:item[@"icon"] ?: @""];
config.title = item[@"title"];
config.imagePlacement = NSDirectionalRectEdgeTop;
config.imagePadding = 5;
btn.configuration = config;
BOOL selected = [item[@"selected"] boolValue];
btn.tintColor = selected ? [UIColor blueColor] : [UIColor whiteColor];
btn.titleLabel.font = [UIFont systemFontOfSize:10];
btn.tag = i;
[btn addTarget:self action:@selector(tabButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btn];
[buttons addObject:btn];
}
self.tabButtons = buttons;
[self setupTabButtonConstraints];
}
- (void)setupTabButtonConstraints {
for (NSInteger i = 0; i < self.tabButtons.count; i++) {
UIButton *btn = self.tabButtons[i];
btn.translatesAutoresizingMaskIntoConstraints = NO;
[NSLayoutConstraint activateConstraints:@[
[btn.widthAnchor constraintEqualToAnchor:self.widthAnchor multiplier:1.0/self.tabButtons.count],
[btn.heightAnchor constraintEqualToAnchor:self.heightAnchor],
[btn.centerYAnchor constraintEqualToAnchor:self.centerYAnchor],
(i == 0) ? [btn.leadingAnchor constraintEqualToAnchor:self.leadingAnchor] :
[btn.leadingAnchor constraintEqualToAnchor:self.tabButtons[i-1].trailingAnchor],
]];
}
// TabBar自身高度
[self.heightAnchor constraintEqualToConstant:60].active = YES;
}
- (void)tabButtonTapped:(UIButton *)sender {
self.selectedIndex = sender.tag;
for (UIButton *btn in self.tabButtons) {
btn.tintColor = (btn.tag == sender.tag) ? [UIColor blueColor] : [UIColor whiteColor];
}
if ([self.delegate respondsToSelector:@selector(tabBarDidSelectIndex:)]) {
[self.delegate tabBarDidSelectIndex:sender.tag];
}
}
// 外部设置选中索引时更新样式
- (void)setSelectedIndex:(NSInteger)selectedIndex {
_selectedIndex = selectedIndex;
for (UIButton *btn in self.tabButtons) {
btn.tintColor = (btn.tag == selectedIndex) ? [UIColor blueColor] : [UIColor whiteColor];
}
}
@end

18
HC/CountryModel.h

@ -0,0 +1,18 @@
//
// CountryModel.h
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import <Foundation/Foundation.h>
@interface CountryModel : NSObject
@property (nonatomic, copy) NSString *code; //
@property (nonatomic, copy) NSString *name; //
@property (nonatomic, copy) NSString *vcClassName; //
+ (instancetype)modelWithCode:(NSString *)code
name:(NSString *)name
vcClassName:(NSString *)vcClassName;
@end

20
HC/CountryModel.m

@ -0,0 +1,20 @@
//
// CountryModel.m
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import "CountryModel.h"
@implementation CountryModel
+ (instancetype)modelWithCode:(NSString *)code
name:(NSString *)name
vcClassName:(NSString *)vcClassName {
CountryModel *model = [[self alloc] init];
model.code = code;
model.name = name;
model.vcClassName = vcClassName;
return model;
}
@end

45
HC/HomeViewController.h

@ -0,0 +1,45 @@
//
// HomeViewController.h
// HC
//
// Created by huilinLi on 2025/11/18.
//
#import <UIKit/UIKit.h>
#import "CommonTabBar.h"
NS_ASSUME_NONNULL_BEGIN
@interface HomeViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate,CommonTabBarDelegate>
@property (nonatomic, strong) UILabel *successLabel;
@property (nonatomic, strong) UITextField *searchField;
@property (nonatomic, strong) UIImageView *logoImage;
@property (nonatomic, strong) UIImageView *flagIcon;
@property (nonatomic, strong) UIButton *messageBtn;
@property (nonatomic, strong) UIScrollView *functionScrollView;
@property (nonatomic, strong) NSMutableArray<UIButton *> *functionBtns;
@property (nonatomic, strong) UIScrollView *bannerScrollView;
@property (nonatomic, strong) UIPageControl *bannerPageControl;
@property (nonatomic, strong) UIView *tabContainer;
@property (nonatomic, strong) UIButton *courseBtn; //
@property (nonatomic, strong) UIButton *infoBtn; //
@property (nonatomic, strong) UIButton *activityBtn; //
@property (nonatomic, strong) UIView *courseUnderline; // 线
@property (nonatomic, strong) UIView *infoUnderline; // 线
@property (nonatomic, strong) UIView *activityUnderline;// 线
@property (nonatomic, strong) UITableView *courseTableView;
// @property (nonatomic, strong) UIView *commonTabBar;
@property (nonatomic, strong) CommonTabBar *commonTabBar;
@property (nonatomic, strong) UIButton *homeTabBtn;
@property (nonatomic, strong) UIButton *marketTabBtn;
@property (nonatomic, strong) UIButton *favoritesTabBtn;
@property (nonatomic, strong) UIButton *mineTabBtn;
@property (nonatomic, strong) UIImageView *redPacketIcon;
@property (nonatomic, strong) NSArray *functionIcons;
@property (nonatomic, strong) NSArray *courseData;
@property (nonatomic, strong) NSTimer *bannerTimer; //
@property (nonatomic, assign) NSInteger currentBannerIndex; //
@end
NS_ASSUME_NONNULL_END

634
HC/HomeViewController.m

@ -0,0 +1,634 @@
//
// HomeViewController.m
// HC
//
// Created by huilinLi on 2025/11/18.
//
#import <UIKit/UIKit.h>
#import "HomeViewController.h"
#import "MyViewController.h"
#import "CommonTabBar.h"
#import "QuotationViewController.h"
@implementation HomeViewController
- (void)viewDidLoad {
self.view.backgroundColor = [UIColor blackColor];
[self setupData];
[self setupSubviews];
[self setupConstraints];
[self selectButton:self.courseBtn];// 课程
}
-(void) setupSubviews{
// 搜索框左边logo
_logoImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo"]];
_logoImage.contentMode = UIViewContentModeScaleAspectFit;// 保持比例
_logoImage.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_logoImage];
// 搜索框
_searchField = [[UITextField alloc] init];
_searchField.placeholder = @"股票名称/代码";
NSAttributedString *placeholder = [[NSAttributedString alloc] initWithString:@"股票名称/代码" attributes:@{
NSForegroundColorAttributeName: [UIColor whiteColor]
}];
_searchField.attributedPlaceholder = placeholder;
_searchField.textColor = [UIColor whiteColor];
_searchField.backgroundColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
_searchField.layer.cornerRadius = 15;
_searchField.leftView = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"magnifyingglass"]];
_searchField.leftViewMode = UITextFieldViewModeAlways;
_searchField.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_searchField];
// 市场配置
_flagIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"singapore_flag"]];
_flagIcon.contentMode = UIViewContentModeScaleAspectFit;
_flagIcon.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_flagIcon];
// 消息
_messageBtn = [UIButton buttonWithType:UIButtonTypeSystem];
UIButtonConfiguration *config = [UIButtonConfiguration plainButtonConfiguration];
config.image = [UIImage systemImageNamed:@"message"];
config.baseForegroundColor = [UIColor whiteColor];
// 富文本
NSAttributedString *attributedTitle = [[NSAttributedString alloc] initWithString:@"15" attributes:@{
NSFontAttributeName: [UIFont systemFontOfSize:10],
NSForegroundColorAttributeName: [UIColor whiteColor]
}];
config.attributedTitle = attributedTitle;
config.imagePadding = -5;
config.contentInsets = NSDirectionalEdgeInsetsMake(0, 0, 0, 0);// 内容边距
[_messageBtn setConfiguration:config];
_messageBtn.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_messageBtn];
// 功能按钮数组初始化
_functionBtns = [NSMutableArray array];
for (NSDictionary *dict in _functionIcons) {
UIButtonConfiguration *config = [UIButtonConfiguration plainButtonConfiguration];
UIImage *logoImage = [UIImage imageNamed:@"logo"];
UIGraphicsBeginImageContextWithOptions(CGSizeMake(40, 40), NO, 0);// 开启图形上下文,((尺寸,尺寸),是否不透明,缩放因子)
[logoImage drawInRect:CGRectMake(0, 0, 40, 40)];// 调整,等比缩放
UIImage *resizedLogo = UIGraphicsGetImageFromCurrentImageContext();// 获得调整后的
UIGraphicsEndImageContext();// 关闭图形上下文
config.image = resizedLogo;
// 按钮文字,富文本
NSAttributedString *titleAttr = [[NSAttributedString alloc] initWithString:dict[@"title"] attributes:@{
NSFontAttributeName: [UIFont systemFontOfSize:13],
NSForegroundColorAttributeName: [UIColor whiteColor]
}];
config.attributedTitle = titleAttr;
config.imagePlacement = NSDirectionalRectEdgeTop;
config.imagePadding = 5;
config.baseForegroundColor = [UIColor whiteColor];
UIButton *btn = [UIButton buttonWithConfiguration:config primaryAction:nil];
btn.titleLabel.font = [UIFont systemFontOfSize:12];
btn.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:btn];
[_functionBtns addObject:btn];
}
// 轮播图视图
_bannerScrollView = [[UIScrollView alloc] init];
_bannerScrollView.showsHorizontalScrollIndicator = NO;// 隐藏水平滚动条
_bannerScrollView.pagingEnabled = YES;// 分页
_bannerScrollView.delegate = self;
_bannerScrollView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_bannerScrollView];
// 轮播图内容容器
UIView *bannerContentView = [[UIView alloc] init];
bannerContentView.translatesAutoresizingMaskIntoConstraints = NO;
[_bannerScrollView addSubview:bannerContentView];
// 轮播图片
NSArray *bannerImageNames = @[@"banner2", @"banner1", @"banner2", @"banner1"];
NSMutableArray *bannerImages = [NSMutableArray array];
for (int i = 0; i < bannerImageNames.count; i++) {
UIImageView *bannerImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:bannerImageNames[i]]];
bannerImage.contentMode = UIViewContentModeScaleAspectFill;// 填充
bannerImage.clipsToBounds = YES;// 裁剪超出的
bannerImage.translatesAutoresizingMaskIntoConstraints = NO;
[bannerContentView addSubview:bannerImage];
[bannerImages addObject:bannerImage];
[bannerImage.heightAnchor constraintEqualToAnchor:bannerContentView.heightAnchor].active = YES;
[bannerImage.widthAnchor constraintEqualToAnchor:self.view.widthAnchor].active = YES;
if (i == 0) {
[bannerImage.leadingAnchor constraintEqualToAnchor:bannerContentView.leadingAnchor].active = YES;
} else {
UIImageView *prevImage = bannerImages[i-1];
[bannerImage.leadingAnchor constraintEqualToAnchor:prevImage.trailingAnchor].active = YES;
}
}
// 内容视图宽度(总图片数 * 屏幕宽度)
[bannerContentView.widthAnchor constraintEqualToConstant:self.view.bounds.size.width * bannerImages.count].active = YES;
[NSLayoutConstraint activateConstraints:@[
[bannerContentView.leadingAnchor constraintEqualToAnchor:_bannerScrollView.leadingAnchor],
[bannerContentView.trailingAnchor constraintEqualToAnchor:_bannerScrollView.trailingAnchor],
[bannerContentView.topAnchor constraintEqualToAnchor:_bannerScrollView.topAnchor],
[bannerContentView.bottomAnchor constraintEqualToAnchor:_bannerScrollView.bottomAnchor],
[bannerContentView.heightAnchor constraintEqualToAnchor:_bannerScrollView.heightAnchor],
]];
// 初始第一张
[_bannerScrollView setContentOffset:CGPointMake(self.view.bounds.size.width, 0) animated:NO];
// 页码
_bannerPageControl = [[UIPageControl alloc] init];
_bannerPageControl.currentPageIndicatorTintColor = [UIColor blueColor];
_bannerPageControl.pageIndicatorTintColor = [UIColor lightGrayColor];// 其他页码
_bannerPageControl.numberOfPages = 2;
_bannerPageControl.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_bannerPageControl];
// 初始化定时器(2秒一切)
_bannerTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(autoScrollBanner) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_bannerTimer forMode:NSRunLoopCommonModes];
_currentBannerIndex = 0;
// 课程咨询活动的容器
self.tabContainer = [[UIView alloc] init];
self.tabContainer.backgroundColor = [UIColor blackColor];
self.tabContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.tabContainer];
// 课程
_courseBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_courseBtn setTitle:@"课程" forState:UIControlStateNormal];
_courseBtn.titleLabel.font = [UIFont systemFontOfSize:14];
[_courseBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[_courseBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
_courseBtn.backgroundColor = [UIColor blackColor];
//[_courseBtn setBackgroundColor:[UIColor blackColor]];
[_courseBtn addTarget:self action:@selector(tabButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
_courseBtn.tag = 100;
_courseBtn.translatesAutoresizingMaskIntoConstraints = NO;
[self.tabContainer addSubview:_courseBtn];
// 资讯
_infoBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_infoBtn setTitle:@"资讯" forState:UIControlStateNormal];
_infoBtn.titleLabel.font = [UIFont systemFontOfSize:14];
//_infoBtn.backgroundColor = [UIColor blackColor];
[_infoBtn setBackgroundColor:[UIColor blackColor]];
[_infoBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[_infoBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[_infoBtn addTarget:self action:@selector(tabButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
_infoBtn.tag = 101;
_infoBtn.translatesAutoresizingMaskIntoConstraints = NO;
[self.tabContainer addSubview:_infoBtn];
// 活动
_activityBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[_activityBtn setTitle:@"活动" forState:UIControlStateNormal];
_activityBtn.titleLabel.font = [UIFont systemFontOfSize:14];
//_activityBtn.backgroundColor = [UIColor blackColor];
[_activityBtn setBackgroundColor:[UIColor blackColor]];
[_activityBtn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[_activityBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[_activityBtn addTarget:self action:@selector(tabButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
_activityBtn.tag = 102;
_activityBtn.translatesAutoresizingMaskIntoConstraints = NO;
[self.tabContainer addSubview:_activityBtn];
// 课程下划线
_courseUnderline = [[UIView alloc] init];
_courseUnderline.backgroundColor = [UIColor blueColor];
_courseUnderline.hidden = YES;
_courseUnderline.translatesAutoresizingMaskIntoConstraints = NO;
[self.tabContainer addSubview:_courseUnderline];
// 资讯下划线
_infoUnderline = [[UIView alloc] init];
_infoUnderline.backgroundColor = [UIColor blueColor];
_infoUnderline.hidden = YES;
_infoUnderline.translatesAutoresizingMaskIntoConstraints = NO;
[self.tabContainer addSubview:_infoUnderline];
// 活动下划线
_activityUnderline = [[UIView alloc] init];
_activityUnderline.backgroundColor = [UIColor blueColor];
_activityUnderline.hidden = YES;
_activityUnderline.translatesAutoresizingMaskIntoConstraints = NO;
[self.tabContainer addSubview:_activityUnderline];
// 课程列表TableView
_courseTableView = [[UITableView alloc] init];
_courseTableView.backgroundColor = [UIColor blackColor];
_courseTableView.separatorStyle = UITableViewCellSeparatorStyleNone;// 隐藏分割线
[_courseTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CourseCell"];
_courseTableView.delegate = self;
_courseTableView.dataSource = self;// 数据源
_courseTableView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_courseTableView];
// 红包
_redPacketIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo"]];
_redPacketIcon.contentMode = UIViewContentModeScaleAspectFit;
_redPacketIcon.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_redPacketIcon];
NSArray *tabItems = @[
@{@"title":@"首页", @"icon":@"house.fill", @"selected":@YES},
@{@"title":@"行情", @"icon":@"chart.line.uptrend.xyaxis", @"selected":@NO},
@{@"title":@"自选", @"icon":@"plus", @"selected":@NO},
@{@"title":@"我的", @"icon":@"person", @"selected":@NO}
];
self.commonTabBar = [[CommonTabBar alloc] initWithTabItems:tabItems];
self.commonTabBar.delegate = self;
[self.view addSubview:self.commonTabBar];
// 登录提示
_successLabel = [[UILabel alloc] init];
_successLabel.text = @"登录成功";
_successLabel.font = [UIFont systemFontOfSize:20];
_successLabel.textColor = [UIColor whiteColor];
_successLabel.numberOfLines = 0;
_successLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_successLabel];
// 标签容器和按钮约束
[NSLayoutConstraint activateConstraints:@[
// 标签容器,轮播图下15,左15,右15,高30
[self.tabContainer.topAnchor constraintEqualToAnchor: _bannerScrollView.bottomAnchor constant:15],
[self.tabContainer.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor constant:15],
[self.tabContainer.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor constant:-15],
[self.tabContainer.heightAnchor constraintEqualToConstant:30],
// 按钮均分宽度
// 课程左齐容器,垂直居中,宽度1/3
[_courseBtn.leadingAnchor constraintEqualToAnchor: self.tabContainer.leadingAnchor],
[_courseBtn.centerYAnchor constraintEqualToAnchor: self.tabContainer.centerYAnchor],
[_courseBtn.widthAnchor constraintEqualToAnchor: self.tabContainer.widthAnchor multiplier:1.0/3.0],
// 咨询左对齐课程右侧
[_infoBtn.leadingAnchor constraintEqualToAnchor: _courseBtn.trailingAnchor],
[_infoBtn.centerYAnchor constraintEqualToAnchor: self.tabContainer.centerYAnchor],
[_infoBtn.widthAnchor constraintEqualToAnchor: self.tabContainer.widthAnchor multiplier:1.0/3.0],
// 活动左对齐咨询右侧
[_activityBtn.leadingAnchor constraintEqualToAnchor: _infoBtn.trailingAnchor],
[_activityBtn.trailingAnchor constraintEqualToAnchor: self.tabContainer.trailingAnchor],
[_activityBtn.centerYAnchor constraintEqualToAnchor: self.tabContainer.centerYAnchor],
// 下划线约束
// 底部对齐容器,在button下方正中,宽302
[_courseUnderline.bottomAnchor constraintEqualToAnchor: self.tabContainer.bottomAnchor],
[_courseUnderline.centerXAnchor constraintEqualToAnchor: _courseBtn.centerXAnchor],
[_courseUnderline.widthAnchor constraintEqualToConstant:30],
[_courseUnderline.heightAnchor constraintEqualToConstant:2],
[_infoUnderline.bottomAnchor constraintEqualToAnchor: self.tabContainer.bottomAnchor],
[_infoUnderline.centerXAnchor constraintEqualToAnchor: _infoBtn.centerXAnchor],
[_infoUnderline.widthAnchor constraintEqualToConstant:30],
[_infoUnderline.heightAnchor constraintEqualToConstant:2],
[_activityUnderline.bottomAnchor constraintEqualToAnchor: self.tabContainer.bottomAnchor],
[_activityUnderline.centerXAnchor constraintEqualToAnchor: _activityBtn.centerXAnchor],
[_activityUnderline.widthAnchor constraintEqualToConstant:30],
[_activityUnderline.heightAnchor constraintEqualToConstant:2],
]];
}
-(void) setupConstraints{
// 登录成功提示
[NSLayoutConstraint activateConstraints:@[
[_successLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],// 水平居中
[_successLabel.centerYAnchor constraintEqualToAnchor:self.view.centerYAnchor],// 垂直居中
[_successLabel.widthAnchor constraintEqualToConstant:80],
[_successLabel.heightAnchor constraintEqualToConstant:30],
]];
// Logo图标 搜索框高度下垂直居中,左边距15,宽4040
[NSLayoutConstraint activateConstraints:@[
[_logoImage.centerYAnchor constraintEqualToAnchor: _searchField.centerYAnchor],
[_logoImage.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor constant:15],
[_logoImage.widthAnchor constraintEqualToConstant:40],
[_logoImage.heightAnchor constraintEqualToConstant:40],
]];
// 搜索栏 父视图下50logo左10,国旗左10,高30
[NSLayoutConstraint activateConstraints:@[
[_searchField.topAnchor constraintEqualToAnchor: self.view.topAnchor constant:50],
[_searchField.leadingAnchor constraintEqualToAnchor: _logoImage.trailingAnchor constant:10],
[_searchField.trailingAnchor constraintEqualToAnchor: _flagIcon.leadingAnchor constant:-10],
[_searchField.heightAnchor constraintEqualToConstant:30],
]];
// 国旗图标
[NSLayoutConstraint activateConstraints:@[
[_flagIcon.centerYAnchor constraintEqualToAnchor: _searchField.centerYAnchor],
[_flagIcon.trailingAnchor constraintEqualToAnchor: _messageBtn.leadingAnchor constant:-10],
[_flagIcon.widthAnchor constraintEqualToConstant:40],
[_flagIcon.heightAnchor constraintEqualToConstant:40],
]];
// 消息按钮
[NSLayoutConstraint activateConstraints:@[
[_messageBtn.centerYAnchor constraintEqualToAnchor: _searchField.centerYAnchor],
[_messageBtn.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor constant:-15],
[_messageBtn.widthAnchor constraintEqualToConstant:40],
[_messageBtn.heightAnchor constraintEqualToConstant:40],
]];
// 功能按钮(两行四列,均匀占满整行)
for (int i = 0; i < _functionBtns.count; i++) {
UIButton *btn = _functionBtns[i];
NSLayoutConstraint *topConstraint;
NSLayoutConstraint *widthConstraint = [btn.widthAnchor constraintEqualToAnchor: self.view.widthAnchor multiplier:0.25 constant:-15];
NSLayoutConstraint *heightConstraint = [btn.heightAnchor constraintEqualToConstant:70];
if (i < 4) {
topConstraint = [btn.topAnchor constraintEqualToAnchor: _searchField.bottomAnchor constant:20];
NSLayoutConstraint *leadingConstraint;
if (i == 0) {
leadingConstraint = [btn.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor constant:15];
} else {
leadingConstraint = [btn.leadingAnchor constraintEqualToAnchor: _functionBtns[i-1].trailingAnchor constant:0];
}
[NSLayoutConstraint activateConstraints:@[topConstraint, leadingConstraint, widthConstraint, heightConstraint]];
} else {
topConstraint = [btn.topAnchor constraintEqualToAnchor: _functionBtns[i-4].bottomAnchor constant:10];
NSLayoutConstraint *leadingConstraint;
if (i == 4) {
leadingConstraint = [btn.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor constant:15];
} else {
leadingConstraint = [btn.leadingAnchor constraintEqualToAnchor: _functionBtns[i-1].trailingAnchor constant:0];
}
[NSLayoutConstraint activateConstraints:@[topConstraint, leadingConstraint, widthConstraint, heightConstraint]];
}
}
// 轮播图ScrollView 顶部距离最后一个功能按钮20,左右对齐父视图,高150
[NSLayoutConstraint activateConstraints:@[
[_bannerScrollView.topAnchor constraintEqualToAnchor: _functionBtns.lastObject.bottomAnchor constant:20],
[_bannerScrollView.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor],
[_bannerScrollView.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor],
[_bannerScrollView.heightAnchor constraintEqualToConstant:150],
]];
// 轮播图PageControl,底部距离轮播图5
[NSLayoutConstraint activateConstraints:@[
[_bannerPageControl.bottomAnchor constraintEqualToAnchor: _bannerScrollView.bottomAnchor constant:-5],
[_bannerPageControl.centerXAnchor constraintEqualToAnchor: self.view.centerXAnchor],
]];
// 课程列表 顶部距离标签容器20,左右对齐父视图,底部tabBar
[NSLayoutConstraint activateConstraints:@[
[_courseTableView.topAnchor constraintEqualToAnchor: self.tabContainer.bottomAnchor constant:20],
[_courseTableView.leadingAnchor constraintEqualToAnchor: self.view.leadingAnchor],
[_courseTableView.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor],
[_courseTableView.bottomAnchor constraintEqualToAnchor: _commonTabBar.topAnchor]
]];
// 红包图标
[NSLayoutConstraint activateConstraints:@[
[_redPacketIcon.bottomAnchor constraintEqualToAnchor: _courseTableView.bottomAnchor constant:-200],
[_redPacketIcon.trailingAnchor constraintEqualToAnchor: self.view.trailingAnchor constant:-20],
[_redPacketIcon.widthAnchor constraintEqualToConstant:60],
[_redPacketIcon.heightAnchor constraintEqualToConstant:60],
]];
// 底部页面按钮 底部对齐安全区域,左右对齐父视图
[_commonTabBar.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor].active = YES;
[_commonTabBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor].active = YES;
[_commonTabBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor].active = YES;
}
- (void)setupData {
_functionIcons = @[// 先都用logo
@{@"title":@"全球指数"},
@{@"title":@"浏览历史"},
@{@"title":@"机构"},
@{@"title":@"弘历学堂"},
@{@"title":@"自选"},
@{@"title":@"商店"},
@{@"title":@"猎庄选股"},
@{@"title":@"智能机器人"}
];
_courseData = @[
@{@"cover":@"course1", @"title":@"John Lu & Robert Xu “发财线”课程回顾!", @"lecturer":@"Homily Lecturer"},
@{@"cover":@"event2", @"title":@"孩子炒股老亏钱,多半是废了", @"lecturer":@"kaslana"},
@{@"cover":@"course3", @"title":@"论持久战", @"lecturer":@"教员先生"}
];
}
#pragma mark - 标签方法
- (void)tabButtonTapped:(UIButton *)sender {
[self selectButton:sender];
// 根据标签切换
switch (sender.tag) {
case 100:
_courseData = @[
@{@"cover":@"course1", @"title":@"John Lu & Robert Xu “发财线”课程回顾!", @"lecturer":@"Homily Lecturer"},
@{@"cover":@"event2", @"title":@"孩子炒股老亏钱,多半是废了", @"lecturer":@"kaslana"},
@{@"cover":@"course3", @"title":@"论持久战", @"lecturer":@"教员先生"}
];
break;
case 101:
_courseData = @[
@{@"cover":@"news1", @"title":@"objective-c从入门到入土", @"lecturer":@"财经资讯"},
@{@"cover":@"news2", @"title":@"线程池核心参数详解", @"lecturer":@"财经资讯"},
@{@"cover":@"news3", @"title":@"redis集群-主从、哨兵、分片", @"lecturer":@"财经资讯"}
];
break;
case 102:
_courseData = @[
@{@"cover":@"event1", @"title":@"SpringCloud入门到放弃", @"lecturer":@"活动预告"},
@{@"cover":@"event2", @"title":@"孩子炒股老亏钱,多半是废了", @"lecturer":@"活动预告"},
@{@"cover":@"event3", @"title":@"mySQL:从删库到跑路", @"lecturer":@"活动预告"}
];
break;
}
[_courseTableView reloadData];
}
- (void) pushMine {
MyViewController *myViewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:myViewController animated:YES];
}
- (void)selectButton:(UIButton *)selectedButton {
_courseBtn.selected = NO;
_infoBtn.selected = NO;
_activityBtn.selected = NO;
_courseBtn.titleLabel.font = [UIFont systemFontOfSize:14];
_infoBtn.titleLabel.font = [UIFont systemFontOfSize:14];
_activityBtn.titleLabel.font = [UIFont systemFontOfSize:14];
_courseUnderline.hidden = YES;
_infoUnderline.hidden = YES;
_activityUnderline.hidden = YES;
// 设置选中按钮状态
selectedButton.selected = YES;
selectedButton.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
// 显示对应下划线
if (selectedButton == _courseBtn) {
_courseUnderline.hidden = NO;
} else if (selectedButton == _infoBtn) {
_infoUnderline.hidden = NO;
} else if (selectedButton == _activityBtn) {
_activityUnderline.hidden = NO;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == _bannerScrollView) {
CGFloat screenWidth = self.view.bounds.size.width;
NSInteger currentOffsetX = scrollView.contentOffset.x;
NSInteger page = currentOffsetX / screenWidth;
// 首尾拼接图无缝跳转
if (page == 0) {
page = 2;
[scrollView setContentOffset:CGPointMake(screenWidth * page, 0) animated:NO];
} else if (page == 3) {
page = 1;
[scrollView setContentOffset:CGPointMake(screenWidth * page, 0) animated:NO];
}
_currentBannerIndex = (page - 1) % 2;
_bannerPageControl.currentPage = _currentBannerIndex;
// 重启定时器
[_bannerTimer invalidate];
_bannerTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(autoScrollBanner)
userInfo:nil
repeats:YES];
}
}
- (void)autoScrollBanner {
CGFloat screenWidth = self.view.bounds.size.width;
// 直接基于真实索引计算下一页,避免contentOffset的延迟问题
_currentBannerIndex = (_currentBannerIndex + 1) % 2; // 0→1→0循环
NSInteger targetPage = _currentBannerIndex + 1; // 对应拼接后的页面(1/2
// 处理尾部拼接图的无缝跳转
if (targetPage > 2) {
targetPage = 1;
[_bannerScrollView setContentOffset:CGPointMake(screenWidth * targetPage, 0) animated:NO];
}
[_bannerScrollView setContentOffset:CGPointMake(screenWidth * targetPage, 0) animated:YES];
_bannerPageControl.currentPage = _currentBannerIndex;
}
- (void) pushQuotation {
QuotationViewController *quotationViewController = [[QuotationViewController alloc] init];
[self.navigationController pushViewController:quotationViewController animated:YES];
}
- (void)tabBarDidSelectIndex:(NSInteger)index {
if (index == 3) {
[self pushMine];
}
else if (index == 0) {
}
else if (index == 1) {
[self pushQuotation];
}
else if (index == 2) {
// 自选
}
}
#pragma mark - 视图即将消失
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[_bannerTimer invalidate];// 销毁定时器
_bannerTimer = nil;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
self->_successLabel.alpha = 0;
} completion:^(BOOL finished) {
[self->_successLabel removeFromSuperview];
}];
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _courseData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CourseCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
for (UIView *subview in cell.contentView.subviews) {
[subview removeFromSuperview];
}
NSDictionary *course = _courseData[indexPath.row];
UIImageView *coverView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:course[@"cover"]]];
coverView.contentMode = UIViewContentModeScaleAspectFill;
coverView.clipsToBounds = YES;
coverView.frame = CGRectMake(15, 10, 140, 100);
[cell.contentView addSubview:coverView];
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(170, 10, 220, 60)];
titleLabel.text = course[@"title"];
titleLabel.textColor = [UIColor whiteColor];
titleLabel.font = [UIFont systemFontOfSize:14];
titleLabel.numberOfLines = 3;
[cell.contentView addSubview:titleLabel];
UILabel *lecturerLabel = [[UILabel alloc] initWithFrame:CGRectMake(170, 75, 120, 30)];
lecturerLabel.text = course[@"lecturer"];
lecturerLabel.textColor = [UIColor lightGrayColor];
lecturerLabel.font = [UIFont systemFontOfSize:14];
[cell.contentView addSubview:lecturerLabel];
UIView *bottomLine = [[UIView alloc] init];
bottomLine.backgroundColor = [UIColor lightGrayColor];
bottomLine.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:bottomLine];
[NSLayoutConstraint activateConstraints:@[
[bottomLine.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:20], // 左边距15
[bottomLine.trailingAnchor constraintEqualToAnchor:cell.contentView.trailingAnchor constant:-20], // 右边距15
[bottomLine.bottomAnchor constraintEqualToAnchor:cell.contentView.bottomAnchor],
[bottomLine.heightAnchor constraintEqualToConstant:0.2]
]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 120;
}
@end

16
HC/MLXYViewController.h

@ -0,0 +1,16 @@
//
// MLXYViewController.h
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MLXYViewController : UIViewController
@end
NS_ASSUME_NONNULL_END

442
HC/MLXYViewController.m

@ -0,0 +1,442 @@
//
// MLXYViewController.m
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import "MLXYViewController.h"
#import "ChartViewController.h"
@interface MLXYViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) UIButton *mlxyButton;
// 大盘指数
@property (nonatomic, strong) UILabel *marketTitleLabel;
@property (nonatomic, strong) UIView *marketView;
@property (nonatomic, strong) UILabel *marketLine1;
@property (nonatomic, strong) UILabel *marketLine2;
@property (nonatomic, strong) UILabel *marketLine3;
// 板块
@property (nonatomic, strong) UILabel *sectorTitleLabel;
@property (nonatomic, strong) UIButton *sectorBtn;
// 三个板块卡片(分别配置)
@property (nonatomic, strong) UIView *sectorCard1;
@property (nonatomic, strong) UIView *sectorCard2;
@property (nonatomic, strong) UIView *sectorCard3;
// 股票
@property (nonatomic, strong) UIView *stockContainer;
@property (nonatomic, strong) UITableView *stockTableView;
// 股票表头
@property (nonatomic, strong) UIView *stockHeaderView;
// 按钮配置
@property (nonatomic, strong) UIButtonConfiguration *buttonConfig;
// 板块数据配置
@property (nonatomic, strong) NSArray *sectorDataConfig;
@end
@implementation MLXYViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self setupButtonConfig];
[self setupSectorDataConfig];
[self setupSubviews];
[self setupConstraints];
[self marketViewClick];
}
-(void) marketViewClick{
_marketView.userInteractionEnabled = YES;
UITapGestureRecognizer *click = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(marketViewPush)];
[_marketView addGestureRecognizer:click];
}
-(void) marketViewPush{
ChartViewController *chartViewController = [[ChartViewController alloc] init];
[self.navigationController pushViewController:chartViewController animated:YES];
}
- (void)setupButtonConfig {
UIButtonConfiguration *config = [UIButtonConfiguration plainButtonConfiguration];
config.title = @"更多";
config.attributedTitle = [[NSAttributedString alloc] initWithString:@"更多" attributes:@{
NSFontAttributeName: [UIFont systemFontOfSize:14],
NSForegroundColorAttributeName: [UIColor lightGrayColor]
}];
UIImage *image = [[UIImage systemImageNamed:@"chevron.right"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
config.image = image;
config.imagePlacement = NSDirectionalRectEdgeTrailing; // 图片在文字右侧
config.imagePadding = 1;
config.baseForegroundColor = [UIColor lightGrayColor];
_buttonConfig = config;
}
- (void)setupSectorDataConfig {
_sectorDataConfig = @[
@{@"name":@"Health", @"value1":@"1099.683", @"value2":@"27.236",@"value3":@"2.270%"},
@{@"name":@"Others", @"value1":@"2083.783", @"value2":@"0.000",@"value3":@"0.000%"},
@{@"name":@"HLKLI", @"value1":@"987.895", @"value2":@"-1.854",@"value3":@"-0.230%"}
];
}
- (void)setupSubviews {
// 马来西亚按钮
_mlxyButton = [UIButton buttonWithType:UIButtonTypeSystem];
[_mlxyButton setTitle:@"马来西亚" forState:UIControlStateNormal];
[_mlxyButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_mlxyButton setBackgroundColor:[UIColor blueColor]];
_mlxyButton.layer.cornerRadius = 15;
_mlxyButton.titleLabel.font = [UIFont systemFontOfSize:14];
_mlxyButton.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_mlxyButton];
// 大盘指数
_marketTitleLabel = [[UILabel alloc] init];
_marketTitleLabel.text = @"大盘指数";
_marketTitleLabel.textColor = [UIColor whiteColor];
_marketTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
_marketTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_marketTitleLabel];
// 绿色卡片
_marketView = [[UIView alloc] init];
_marketView.backgroundColor = [UIColor greenColor];
_marketView.layer.cornerRadius = 8;
_marketView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_marketView];
_marketLine1 = [[UILabel alloc] init];
_marketLine1.text = @"富时马来西亚KLCI";
_marketLine1.textColor = [UIColor whiteColor];
_marketLine1.font = [UIFont fontWithName:@"Helvetica-Bold" size:12];
_marketLine1.textAlignment = NSTextAlignmentCenter;
_marketLine1.translatesAutoresizingMaskIntoConstraints = NO;
[_marketView addSubview:_marketLine1];
_marketLine2 = [[UILabel alloc] init];
_marketLine2.text = @"1624.500";
_marketLine2.textColor = [UIColor whiteColor];
_marketLine2.font = [UIFont boldSystemFontOfSize:17];
_marketLine2.textAlignment = NSTextAlignmentCenter;
_marketLine2.translatesAutoresizingMaskIntoConstraints = NO;
[_marketView addSubview:_marketLine2];
_marketLine3 = [[UILabel alloc] init];
_marketLine3.text = @"12.760 0.792%";
_marketLine3.textColor = [UIColor whiteColor];
_marketLine3.font = [UIFont boldSystemFontOfSize:12];
_marketLine3.textAlignment = NSTextAlignmentCenter;
_marketLine3.translatesAutoresizingMaskIntoConstraints = NO;
[_marketView addSubview:_marketLine3];
// 板块
_sectorTitleLabel = [[UILabel alloc] init];
_sectorTitleLabel.text = @"板块";
_sectorTitleLabel.textColor = [UIColor whiteColor];
_sectorTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
_sectorTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_sectorTitleLabel];
_sectorBtn = [UIButton buttonWithConfiguration:self.buttonConfig primaryAction:nil];
_sectorBtn.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_sectorBtn];
_sectorCard1 = [self createSectorCardWithData:self.sectorDataConfig[0]];
[self.view addSubview:_sectorCard1];
_sectorCard2 = [self createSectorCardWithData:self.sectorDataConfig[1]];
[self.view addSubview:_sectorCard2];
_sectorCard3 = [self createSectorCardWithData:self.sectorDataConfig[2]];
[self.view addSubview:_sectorCard3];
// 股票容器
_stockContainer = [[UIView alloc] init];
_stockContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_stockContainer];
UILabel *stockTitleLabel = [[UILabel alloc] init];
stockTitleLabel.text = @"股票";
stockTitleLabel.textColor = [UIColor whiteColor];
stockTitleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
stockTitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_stockContainer addSubview:stockTitleLabel];
UIButton *stockBtn = [UIButton buttonWithConfiguration:self.buttonConfig primaryAction:nil];
stockBtn.translatesAutoresizingMaskIntoConstraints = NO;
[_stockContainer addSubview:stockBtn];
// 股票列表表头
_stockHeaderView = [[UIView alloc] init];
_stockHeaderView.backgroundColor = [UIColor blackColor];
_stockHeaderView.translatesAutoresizingMaskIntoConstraints = NO;
[_stockContainer addSubview:_stockHeaderView];
NSArray *headerTitles = @[@"名称", @"最新", @"涨幅"];
for (NSInteger i = 0; i < headerTitles.count; i++) {
UILabel *headerLabel = [[UILabel alloc] init];
headerLabel.text = headerTitles[i];
headerLabel.textColor = [UIColor lightGrayColor];
headerLabel.font = [UIFont systemFontOfSize:12];
headerLabel.textAlignment = (i == 0) ? NSTextAlignmentLeft : NSTextAlignmentRight;
headerLabel.translatesAutoresizingMaskIntoConstraints = NO;
[_stockHeaderView addSubview:headerLabel];
if (i == 0) {
[headerLabel.leadingAnchor constraintEqualToAnchor:_stockHeaderView.leadingAnchor constant:15].active = YES;
} else if (i == 1) {
[headerLabel.widthAnchor constraintEqualToConstant:60].active = YES;
[headerLabel.trailingAnchor constraintEqualToAnchor:_stockHeaderView.trailingAnchor constant:-110].active = YES;
} else {
[headerLabel.widthAnchor constraintEqualToConstant:80].active = YES;
[headerLabel.trailingAnchor constraintEqualToAnchor:_stockHeaderView.trailingAnchor constant:-30].active = YES;
}
[headerLabel.centerYAnchor constraintEqualToAnchor:_stockHeaderView.centerYAnchor].active = YES;
}
_stockTableView = [[UITableView alloc] init];
_stockTableView.backgroundColor = [UIColor blackColor];
_stockTableView.separatorStyle = UITableViewCellSeparatorStyleNone;// 隐藏单元格之间的分隔线
//SingleLine 默认,1px的分割线
_stockTableView.delegate = self;
_stockTableView.dataSource = self;
[_stockTableView registerClass:[UITableViewCell class]// 单元格复用类
forCellReuseIdentifier:@"StockCell"];// 复用标识
_stockTableView.translatesAutoresizingMaskIntoConstraints = NO;
[_stockContainer addSubview:_stockTableView];
}
- (UIView *)createSectorCardWithData:(NSDictionary *)data {
UIView *card = [[UIView alloc] init];
card.backgroundColor = [UIColor darkGrayColor];
card.layer.cornerRadius = 8;
card.translatesAutoresizingMaskIntoConstraints = NO;
// 名称
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.text = data[@"name"];
nameLabel.textColor = [UIColor whiteColor];
nameLabel.font = [UIFont systemFontOfSize:14];
nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:nameLabel];
// 数值
UILabel *value1Label = [[UILabel alloc] init];
value1Label.text = data[@"value1"];
value1Label.textColor = [UIColor greenColor];
value1Label.font = [UIFont systemFontOfSize:16 weight:UIFontWeightBold];
value1Label.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:value1Label];
// 涨幅
UILabel *value2Label = [[UILabel alloc] init];
value2Label.text = data[@"value2"];
value2Label.textColor = [UIColor greenColor];
value2Label.font = [UIFont systemFontOfSize:12];
value2Label.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:value2Label];
UILabel *value3Label = [[UILabel alloc] init];
value3Label.text = data[@"value3"];
value3Label.textColor = [UIColor greenColor];
value3Label.font = [UIFont systemFontOfSize:12];
value3Label.translatesAutoresizingMaskIntoConstraints = NO;
[card addSubview:value3Label];
[NSLayoutConstraint activateConstraints:@[
[nameLabel.topAnchor constraintEqualToAnchor:card.topAnchor constant:7],
[nameLabel.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:10],
[value1Label.topAnchor constraintEqualToAnchor:nameLabel.bottomAnchor constant:10],
[value1Label.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:10],
[value2Label.topAnchor constraintEqualToAnchor:value1Label.bottomAnchor constant:7],
[value2Label.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:10],
[value3Label.topAnchor constraintEqualToAnchor:value2Label.bottomAnchor constant:6],
[value3Label.leadingAnchor constraintEqualToAnchor:card.leadingAnchor constant:10]
]];
return card;
}
- (void)setupConstraints {
// 马来西亚按钮
NSLayoutConstraint *btnTop = [_mlxyButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor];
NSLayoutConstraint *btnLeft = [_mlxyButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:15];
NSLayoutConstraint *btnWidth = [_mlxyButton.widthAnchor constraintEqualToConstant:90];
NSLayoutConstraint *btnHeight = [_mlxyButton.heightAnchor constraintEqualToConstant:30];
[NSLayoutConstraint activateConstraints:@[btnTop, btnLeft, btnWidth, btnHeight]];
// 大盘
NSLayoutConstraint *marketTitleTop = [_marketTitleLabel.topAnchor constraintEqualToAnchor:_mlxyButton.bottomAnchor constant:10];
NSLayoutConstraint *marketTitleLeft = [_marketTitleLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:15];
[NSLayoutConstraint activateConstraints:@[marketTitleTop, marketTitleLeft]];
NSLayoutConstraint *marketCardTop = [_marketView.topAnchor constraintEqualToAnchor:_marketTitleLabel.bottomAnchor constant:10];
NSLayoutConstraint *marketCardLeft = [_marketView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:15];
NSLayoutConstraint *marketCardWidth = [_marketView.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:0.3];
NSLayoutConstraint *marketCardHeight = [_marketView.heightAnchor constraintEqualToConstant:100];
[NSLayoutConstraint activateConstraints:@[marketCardTop, marketCardLeft, marketCardWidth, marketCardHeight]];
NSLayoutConstraint *line1Top = [_marketLine1.topAnchor constraintEqualToAnchor:_marketView.topAnchor constant:10];
NSLayoutConstraint *line1CenterX = [_marketLine1.centerXAnchor constraintEqualToAnchor:_marketView.centerXAnchor];
NSLayoutConstraint *line2Top = [_marketLine2.topAnchor constraintEqualToAnchor:_marketLine1.bottomAnchor constant:15];
NSLayoutConstraint *line2CenterX = [_marketLine2.centerXAnchor constraintEqualToAnchor:_marketView.centerXAnchor];
NSLayoutConstraint *line3Top = [_marketLine3.topAnchor constraintEqualToAnchor:_marketLine2.bottomAnchor constant:12];
NSLayoutConstraint *line3CenterX = [_marketLine3.centerXAnchor constraintEqualToAnchor:_marketView.centerXAnchor];
[NSLayoutConstraint activateConstraints:@[line1Top, line1CenterX, line2Top, line2CenterX, line3Top, line3CenterX]];
// 板块
NSLayoutConstraint *sectorTitleTop = [_sectorTitleLabel.topAnchor constraintEqualToAnchor:_marketView.bottomAnchor constant:20];
NSLayoutConstraint *sectorTitleLeft = [_sectorTitleLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:15];
[NSLayoutConstraint activateConstraints:@[sectorTitleTop, sectorTitleLeft]];
NSLayoutConstraint *sectorBtnTop = [_sectorBtn.centerYAnchor constraintEqualToAnchor:_sectorTitleLabel.centerYAnchor];
NSLayoutConstraint *sectorBtnRight = [_sectorBtn.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-15];
[NSLayoutConstraint activateConstraints:@[sectorBtnTop, sectorBtnRight]];
NSLayoutConstraint *card1Top = [_sectorCard1.topAnchor constraintEqualToAnchor:_sectorTitleLabel.bottomAnchor constant:10];
NSLayoutConstraint *card1Left = [_sectorCard1.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:8];
NSLayoutConstraint *card1Width = [_sectorCard1.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:0.3];
NSLayoutConstraint *card1Height = [_sectorCard1.heightAnchor constraintEqualToConstant:100];
[NSLayoutConstraint activateConstraints:@[card1Top, card1Left, card1Width, card1Height]];
NSLayoutConstraint *card2Top = [_sectorCard2.topAnchor constraintEqualToAnchor:_sectorCard1.topAnchor];
NSLayoutConstraint *card2Left = [_sectorCard2.leadingAnchor constraintEqualToAnchor:_sectorCard1.trailingAnchor constant:8];
NSLayoutConstraint *card2Width = [_sectorCard2.widthAnchor constraintEqualToAnchor:_sectorCard1.widthAnchor];
NSLayoutConstraint *card2Height = [_sectorCard2.heightAnchor constraintEqualToAnchor:_sectorCard1.heightAnchor];
[NSLayoutConstraint activateConstraints:@[card2Top, card2Left, card2Width, card2Height]];
NSLayoutConstraint *card3Top = [_sectorCard3.topAnchor constraintEqualToAnchor:_sectorCard1.topAnchor];
NSLayoutConstraint *card3Left = [_sectorCard3.leadingAnchor constraintEqualToAnchor:_sectorCard2.trailingAnchor constant:8];
NSLayoutConstraint *card3Right = [_sectorCard3.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-16];
// *card3Width = [_sectorCard3.widthAnchor constraintEqualToAnchor:_sectorCard1.widthAnchor];都行
NSLayoutConstraint *card3Height = [_sectorCard3.heightAnchor constraintEqualToAnchor:_sectorCard1.heightAnchor];
[NSLayoutConstraint activateConstraints:@[card3Top, card3Left, card3Right, card3Height]];
// 股票容器
NSLayoutConstraint *stockTop = [_stockContainer.topAnchor constraintEqualToAnchor:_sectorCard1.bottomAnchor constant:20];
NSLayoutConstraint *stockLeft = [_stockContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor];
NSLayoutConstraint *stockRight = [_stockContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor];
NSLayoutConstraint *stockBottom = [_stockContainer.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor];
[NSLayoutConstraint activateConstraints:@[stockTop, stockLeft, stockRight, stockBottom]];
UILabel *stockTitleLabel = _stockContainer.subviews[0];
UIButton *stockBtn = _stockContainer.subviews[1];
NSLayoutConstraint *stockTitleTop = [stockTitleLabel.topAnchor constraintEqualToAnchor:_stockContainer.topAnchor constant:15];
NSLayoutConstraint *stockTitleLeft = [stockTitleLabel.leadingAnchor constraintEqualToAnchor:_stockContainer.leadingAnchor constant:15];
NSLayoutConstraint *stockBtnTop = [stockBtn.centerYAnchor constraintEqualToAnchor:stockTitleLabel.centerYAnchor];
NSLayoutConstraint *stockBtnRight = [stockBtn.trailingAnchor constraintEqualToAnchor:_stockContainer.trailingAnchor constant:-15];
[NSLayoutConstraint activateConstraints:@[stockTitleTop, stockTitleLeft, stockBtnTop, stockBtnRight]];
// 股票表头
NSLayoutConstraint *headerTop = [_stockHeaderView.topAnchor constraintEqualToAnchor:stockTitleLabel.bottomAnchor constant:10];
NSLayoutConstraint *headerLeft = [_stockHeaderView.leadingAnchor constraintEqualToAnchor:_stockContainer.leadingAnchor];
NSLayoutConstraint *headerRight = [_stockHeaderView.trailingAnchor constraintEqualToAnchor:_stockContainer.trailingAnchor];
NSLayoutConstraint *headerHeight = [_stockHeaderView.heightAnchor constraintEqualToConstant:30];
[NSLayoutConstraint activateConstraints:@[headerTop, headerLeft, headerRight, headerHeight]];
// 股票列表
NSLayoutConstraint *tableTop = [_stockTableView.topAnchor constraintEqualToAnchor:_stockHeaderView.bottomAnchor];
NSLayoutConstraint *tableLeft = [_stockTableView.leadingAnchor constraintEqualToAnchor:_stockContainer.leadingAnchor];
NSLayoutConstraint *tableRight = [_stockTableView.trailingAnchor constraintEqualToAnchor:_stockContainer.trailingAnchor];
NSLayoutConstraint *tableBottom = [_stockTableView.bottomAnchor constraintEqualToAnchor:_stockContainer.bottomAnchor];
[NSLayoutConstraint activateConstraints:@[tableTop, tableLeft, tableRight, tableBottom]];
}
#pragma mark - UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StockCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// 清空复用内容
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
NSArray *stocks = @[
@{@"name":@"PEGASUS HEIGHTS BERHAD", @"code":@"4464", @"price":@"0.010", @"value2":@"100.000%"},
@{@"name":@"SMTRACK BERHAD", @"code":@"0169", @"price":@"0.010", @"value2":@"100.000%"},
@{@"name":@"TXCD BERHAD - ICPS 2020/2030", @"code":@"7145PA", @"price":@"0.020", @"value2":@"33.333%"},
@{@"name":@"DNONCE TECHNOLOGY BHD", @"code":@"7114", @"price":@"0.040", @"value2":@"33.333%"}
];
NSDictionary *stock = stocks[indexPath.row];
// 名称
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.text = stock[@"name"];
nameLabel.textColor = [UIColor whiteColor];
nameLabel.font = [UIFont systemFontOfSize:14];
nameLabel.numberOfLines = 1;
nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:nameLabel];
// 代码
UILabel *codeLabel = [[UILabel alloc] init];
codeLabel.text = stock[@"code"];
codeLabel.textColor = [UIColor lightGrayColor];
codeLabel.font = [UIFont systemFontOfSize:12];
codeLabel.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:codeLabel];
// 价格
UILabel *priceLabel = [[UILabel alloc] init];
priceLabel.text = stock[@"price"];
priceLabel.textColor = [UIColor greenColor];
priceLabel.font = [UIFont systemFontOfSize:14];
priceLabel.textAlignment = NSTextAlignmentRight;
priceLabel.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:priceLabel];
// 涨幅
UILabel *value2Label = [[UILabel alloc] init];
value2Label.text = stock[@"value2"];
value2Label.textColor = [UIColor greenColor];
value2Label.font = [UIFont systemFontOfSize:14];
value2Label.textAlignment = NSTextAlignmentRight;
value2Label.translatesAutoresizingMaskIntoConstraints = NO;
[cell.contentView addSubview:value2Label];
// 约束
[NSLayoutConstraint activateConstraints:@[
[nameLabel.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:15],
[nameLabel.topAnchor constraintEqualToAnchor:cell.contentView.topAnchor constant:10],
[nameLabel.trailingAnchor constraintLessThanOrEqualToAnchor:priceLabel.leadingAnchor constant:-10],
[codeLabel.leadingAnchor constraintEqualToAnchor:cell.contentView.leadingAnchor constant:15],
[codeLabel.topAnchor constraintEqualToAnchor:nameLabel.bottomAnchor constant:5],
[priceLabel.widthAnchor constraintEqualToConstant:60],
[priceLabel.trailingAnchor constraintEqualToAnchor:value2Label.leadingAnchor constant:-10],
[priceLabel.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor],
[value2Label.widthAnchor constraintEqualToConstant:80],
[value2Label.trailingAnchor constraintEqualToAnchor:cell.contentView.trailingAnchor constant:-15],
[value2Label.centerYAnchor constraintEqualToAnchor:cell.contentView.centerYAnchor]
]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60;
}
@end

18
HC/MyViewController.h

@ -0,0 +1,18 @@
//
// MyViewController.h
// HC
//
// Created by huilinLi on 2025/11/25.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class CommonTabBar;
@interface MyViewController : UIViewController
@property (nonatomic, strong) CommonTabBar *tabBar;
@property (nonatomic, strong) UIView *lastSettingItem;
@end
NS_ASSUME_NONNULL_END

390
HC/MyViewController.m

@ -0,0 +1,390 @@
//
// MyViewController.m
// HC
//
// Created by huilinLi on 2025/11/25.
//
#import "MyViewController.h"
#import <UIKit/UIKit.h>
#import "CommonTabBar.h"
#import "HomeViewController.h"
#import "ViewController.h"
#import "QuotationViewController.h"
@implementation MyViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self setupUI];
}
- (void)setupUI {
UIScrollView *scrollView = [[UIScrollView alloc] init];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor blackColor];
[self.view addSubview:scrollView];
UIView *contentView = [[UIView alloc] init];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
contentView.backgroundColor = [UIColor blackColor];
[scrollView addSubview:contentView];
[self setupUserHeaderInContentView:contentView];
[self setupCoinDiamondInContentView:contentView];
[self setupSettingListInContentView:contentView];
[self setupLogoutButtonInContentView:contentView];
[self setupTabBar];
[NSLayoutConstraint activateConstraints:@[
[scrollView.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[scrollView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[scrollView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[scrollView.bottomAnchor constraintEqualToAnchor:self.tabBar.topAnchor],
[contentView.topAnchor constraintEqualToAnchor:scrollView.topAnchor],
[contentView.leadingAnchor constraintEqualToAnchor:scrollView.leadingAnchor],
[contentView.trailingAnchor constraintEqualToAnchor:scrollView.trailingAnchor],
[contentView.bottomAnchor constraintEqualToAnchor:scrollView.bottomAnchor],
[contentView.widthAnchor constraintEqualToAnchor:scrollView.widthAnchor]
]];
}
#pragma mark - 上边儿
- (void)setupUserHeaderInContentView:(UIView *)contentView {
UIButton *settingBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[settingBtn setImage:[UIImage systemImageNamed:@"gearshape"] forState:UIControlStateNormal];
settingBtn.tintColor = [UIColor whiteColor];
settingBtn.translatesAutoresizingMaskIntoConstraints = NO;
[contentView addSubview:settingBtn];
UIImageView *avatar = [self createImageViewWithImage:@"hqz" contentMode:UIViewContentModeScaleAspectFill cornerRadius:40];
[contentView addSubview:avatar];
UILabel *nameLabel = [self createLabelWithText:@"演示机李慧琳" fontSize:18 textColor:[UIColor whiteColor]];
[contentView addSubview:nameLabel];
UILabel *idLabel = [self createLabelWithText:@"ID: 90047681" fontSize:14 textColor:[UIColor whiteColor]];
[contentView addSubview:idLabel];
UIButton *signBtn = [self createButtonWithTitle:@"已签到" bgColor:[UIColor whiteColor] cornerRadius:15];
[signBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[contentView addSubview:signBtn];
[NSLayoutConstraint activateConstraints:@[
[avatar.topAnchor constraintEqualToAnchor:contentView.topAnchor constant:20],
[avatar.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor constant:20],
[avatar.widthAnchor constraintEqualToConstant:80],
[avatar.heightAnchor constraintEqualToConstant:80],
[nameLabel.centerYAnchor constraintEqualToAnchor:avatar.centerYAnchor constant:-10],
[nameLabel.leadingAnchor constraintEqualToAnchor:avatar.trailingAnchor constant:15],
[idLabel.topAnchor constraintEqualToAnchor:nameLabel.bottomAnchor constant:5],
[idLabel.leadingAnchor constraintEqualToAnchor:nameLabel.leadingAnchor],
[signBtn.centerYAnchor constraintEqualToAnchor:avatar.centerYAnchor],
[signBtn.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor constant:-20],
[signBtn.widthAnchor constraintEqualToConstant:90],
[signBtn.heightAnchor constraintEqualToConstant:30],
[settingBtn.topAnchor constraintEqualToAnchor:contentView.topAnchor constant:-35],
[settingBtn.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor constant:-20],
[settingBtn.widthAnchor constraintEqualToConstant:24],
[settingBtn.heightAnchor constraintEqualToConstant:24]
]];
}
#pragma mark - 金币钻石
- (void)setupCoinDiamondInContentView:(UIView *)contentView {
NSArray *itemConfigs = @[
@{@"icon":@"hqz", @"text":@"6011.56"},
@{@"icon":@"hqz", @"text":@"0"}
];
UIView *containerView = [[UIView alloc] init];
containerView.translatesAutoresizingMaskIntoConstraints = NO;
[contentView addSubview:containerView];
for (int i = 0; i < itemConfigs.count; i++) {
NSDictionary *config = itemConfigs[i];
UIButton *btn = [self createInfoButtonWithConfig:config];
btn.tag = 100 + i;
[containerView addSubview:btn];
[NSLayoutConstraint activateConstraints:@[
[btn.topAnchor constraintEqualToAnchor:containerView.topAnchor],
[btn.bottomAnchor constraintEqualToAnchor:containerView.bottomAnchor],
[btn.widthAnchor constraintEqualToAnchor:containerView.widthAnchor multiplier:0.5],
(i == 0) ? [btn.leadingAnchor constraintEqualToAnchor:containerView.leadingAnchor] : [btn.trailingAnchor constraintEqualToAnchor:containerView.trailingAnchor]
]];
}
UIView *verticalDivider = [self createVerticalDivider];
[containerView addSubview:verticalDivider];
[NSLayoutConstraint activateConstraints:@[
[containerView.topAnchor constraintEqualToAnchor:contentView.subviews[1].bottomAnchor constant:20],
[containerView.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor],
[containerView.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor],
[containerView.heightAnchor constraintEqualToConstant:80],
[verticalDivider.centerXAnchor constraintEqualToAnchor:containerView.centerXAnchor],
[verticalDivider.topAnchor constraintEqualToAnchor:containerView.topAnchor constant:10],
[verticalDivider.bottomAnchor constraintEqualToAnchor:containerView.bottomAnchor constant:-10],
[verticalDivider.widthAnchor constraintEqualToConstant:0.5]
]];
}
#pragma mark - 设置列表
- (void)setupSettingListInContentView:(UIView *)contentView {
NSArray *rowTexts = @[
@"账号与安全",
@"服务期限",
@"行情设置",
@"通用设置",
@"金币记录",
@"分享奖励",
@"联系我们",
@"新版本更新",
@"意见反馈",
@"关于Homily Chart"
];
// 金币钻石容器
UIView *coinContainer = contentView.subviews.lastObject;
CGFloat topOffset = 0;
for (int i = 0; i < rowTexts.count; i++) {
UIView *itemView = [self createCommonRowWithText:rowTexts[i]];
[contentView addSubview:itemView];
[NSLayoutConstraint activateConstraints:@[
[itemView.topAnchor constraintEqualToAnchor:coinContainer.bottomAnchor constant:topOffset + 20],
[itemView.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor],
[itemView.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor],
[itemView.heightAnchor constraintEqualToConstant:60]
]];
if (i < rowTexts.count - 1) {
UIView *divider = [self createDividerWithLeading:20];
[contentView addSubview:divider];
[NSLayoutConstraint activateConstraints:@[
[divider.topAnchor constraintEqualToAnchor:itemView.bottomAnchor],
[divider.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor constant:20],
[divider.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor],
[divider.heightAnchor constraintEqualToConstant:0.5]
]];
}
topOffset += 60;
}
self.lastSettingItem = contentView.subviews.lastObject;
}
#pragma mark - 退出登录
- (void)setupLogoutButtonInContentView:(UIView *)contentView {
UIButton *logoutBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[logoutBtn setTitle:@"退出登录" forState:UIControlStateNormal];
[logoutBtn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
logoutBtn.titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
logoutBtn.translatesAutoresizingMaskIntoConstraints = NO;
[logoutBtn addTarget:self action:@selector(logoutTapped) forControlEvents:UIControlEventTouchUpInside];
[contentView addSubview:logoutBtn];
[NSLayoutConstraint activateConstraints:@[
[logoutBtn.topAnchor constraintEqualToAnchor:self.lastSettingItem.bottomAnchor constant:20],
[logoutBtn.centerXAnchor constraintEqualToAnchor:contentView.centerXAnchor],
[logoutBtn.widthAnchor constraintEqualToConstant:120],
[logoutBtn.heightAnchor constraintEqualToConstant:40],
[contentView.bottomAnchor constraintEqualToAnchor:logoutBtn.bottomAnchor constant:20]
]];
}
#pragma mark - 退出登录方法
- (void)logoutTapped {
ViewController *loginVC = [[ViewController alloc] init];
loginVC.hidesBottomBarWhenPushed = YES; // 隐藏TabBar
[self.navigationController pushViewController:loginVC animated:YES];
}
#pragma mark - 底部TabBar
- (void)setupTabBar {
NSArray *tabItems = @[
@{@"title":@"首页", @"icon":@"house.fill", @"selected":@NO},
@{@"title":@"行情", @"icon":@"chart.line.uptrend.xyaxis", @"selected":@NO},
@{@"title":@"自选", @"icon":@"plus", @"selected":@NO},
@{@"title":@"我的", @"icon":@"person", @"selected":@YES}
];
self.tabBar = [[CommonTabBar alloc] initWithTabItems:tabItems];
self.tabBar.delegate = self;
self.tabBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.tabBar];
[NSLayoutConstraint activateConstraints:@[
[self.tabBar.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
[self.tabBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.tabBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.tabBar.heightAnchor constraintEqualToConstant:49]
]];
}
#pragma mark - 工具方法
- (UIButton *)createInfoButtonWithConfig:(NSDictionary *)config {
UIButtonConfiguration *btnConfig = [UIButtonConfiguration plainButtonConfiguration];
NSString *iconName = config[@"icon"];
UIImage *iconImage = [UIImage imageNamed:iconName];
if (!iconImage) {
UIImageSymbolConfiguration *symbolConfig = [UIImageSymbolConfiguration configurationWithPointSize:24 weight:UIFontWeightRegular];
iconImage = [UIImage systemImageNamed:@"dollarsign.circle" withConfiguration:symbolConfig];
} else {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(40, 40), NO, 0);
[iconImage drawInRect:CGRectMake(0, 0, 40, 40)];
iconImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
btnConfig.image = iconImage;
btnConfig.imagePlacement = NSDirectionalRectEdgeTop;
btnConfig.imagePadding = 15;
// 富文本吧
NSAttributedString *titleAttr = [[NSAttributedString alloc] initWithString:config[@"text"] attributes:@{
NSFontAttributeName: [UIFont systemFontOfSize:14],
NSForegroundColorAttributeName: [UIColor whiteColor]
}];
btnConfig.attributedTitle = titleAttr;
btnConfig.baseBackgroundColor = [UIColor clearColor];
btnConfig.baseForegroundColor = [UIColor whiteColor];
UIButton *btn = [UIButton buttonWithConfiguration:btnConfig primaryAction:nil];
btn.translatesAutoresizingMaskIntoConstraints = NO;
[btn addTarget:self action:@selector(infoButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
return btn;
}
- (void)infoButtonTapped:(UIButton *)sender {
if (sender.tag == 100) {
NSLog(@"金币按钮被点击");
} else if (sender.tag == 101) {
NSLog(@"钻石按钮被点击");
}
}
- (UIView *)createVerticalDivider {
UIView *divider = [[UIView alloc] init];
divider.backgroundColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1];
divider.translatesAutoresizingMaskIntoConstraints = NO;
return divider;
}
- (UIImageView *)createImageViewWithImage:(NSString *)imageName contentMode:(UIViewContentMode)mode cornerRadius:(CGFloat)radius {
UIImageView *uiImageView = [[UIImageView alloc] init];
uiImageView.image = [UIImage imageNamed:imageName];
uiImageView.contentMode = mode;
uiImageView.layer.cornerRadius = radius;
uiImageView.clipsToBounds = YES;
uiImageView.translatesAutoresizingMaskIntoConstraints = NO;
return uiImageView;
}
- (UILabel *)createLabelWithText:(NSString *)text fontSize:(CGFloat)size textColor:(UIColor *)color {
UILabel *label = [[UILabel alloc] init];
label.text = text;
label.font = [UIFont systemFontOfSize:size weight:UIFontWeightMedium];
label.textColor = color;
label.translatesAutoresizingMaskIntoConstraints = NO;
return label;
}
- (UIButton *)createButtonWithTitle:(NSString *)title bgColor:(UIColor *)bgColor cornerRadius:(CGFloat)radius {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
[btn setTitle:title forState:UIControlStateNormal];
[btn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
btn.backgroundColor = bgColor;
btn.layer.cornerRadius = radius;
btn.translatesAutoresizingMaskIntoConstraints = NO;
return btn;
}
- (UIView *)createDividerWithLeading:(CGFloat)leading {
UIView *divider = [[UIView alloc] init];
divider.backgroundColor = [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:1];
divider.translatesAutoresizingMaskIntoConstraints = NO;
return divider;
}
- (UIView *)createCommonRowWithText:(NSString *)text {
UIView *rowView = [[UIView alloc] init];
rowView.translatesAutoresizingMaskIntoConstraints = NO;
rowView.backgroundColor = [UIColor clearColor];
UIImageView *logoView = [self createImageViewWithImage:@"hqz"
contentMode:UIViewContentModeScaleAspectFit
cornerRadius:0];
logoView.tintColor = [UIColor blueColor];
[rowView addSubview:logoView];
UILabel *textLabel = [self createLabelWithText:text
fontSize:16
textColor:[UIColor whiteColor]];
[rowView addSubview:textLabel];
UIButton *arrowBtn = [UIButton buttonWithType:UIButtonTypeSystem];
[arrowBtn setImage:[UIImage systemImageNamed:@"chevron.right"] forState:UIControlStateNormal];
[arrowBtn setTintColor:[UIColor lightGrayColor]];
arrowBtn.translatesAutoresizingMaskIntoConstraints = NO;
[rowView addSubview:arrowBtn];
[NSLayoutConstraint activateConstraints:@[
// logo左侧固定
[logoView.centerYAnchor constraintEqualToAnchor:rowView.centerYAnchor],
[logoView.leadingAnchor constraintEqualToAnchor:rowView.leadingAnchor constant:20],
[logoView.widthAnchor constraintEqualToConstant:24],
[logoView.heightAnchor constraintEqualToConstant:24],
// 文字 logo右侧
[textLabel.centerYAnchor constraintEqualToAnchor:logoView.centerYAnchor],
[textLabel.leadingAnchor constraintEqualToAnchor:logoView.trailingAnchor constant:15],
// 箭头 右侧固定
[arrowBtn.centerYAnchor constraintEqualToAnchor:logoView.centerYAnchor],
[arrowBtn.trailingAnchor constraintEqualToAnchor:rowView.trailingAnchor constant:-20]
]];
return rowView;
}
#pragma mark - TabBar
- (void) pushHome {
HomeViewController *homeViewController = [[HomeViewController alloc] init];
[self.navigationController pushViewController:homeViewController animated:YES];
}
- (void) pushQuotation {
QuotationViewController *quotationViewController = [[QuotationViewController alloc] init];
[self.navigationController pushViewController:quotationViewController animated:YES];
}
- (void)tabBarDidSelectIndex:(NSInteger)index {
if (index == 3) {
} else if (index == 0) {
[self pushHome];
} else if (index == 1) {
[self pushQuotation];
} else if (index == 2) {
// 自选
}
}
@end

16
HC/QuotationViewController.h

@ -0,0 +1,16 @@
//
// QuotationViewController.h
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import <UIKit/UIKit.h>
#import "MLXYViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface QuotationViewController : UIViewController
@end
NS_ASSUME_NONNULL_END

258
HC/QuotationViewController.m

@ -0,0 +1,258 @@
//
// QuotationViewController.m
// HC
//
// Created by huilinLi on 2025/11/26.
//
#import "QuotationViewController.h"
#import "CountryModel.h"
#import "MLXYViewController.h" // 马来西亚
#import "CNViewController.h" // 中国
#import "CommonTabBar.h"
#import "HomeViewController.h"
#import "MyViewController.h"
@interface QuotationViewController () <UICollectionViewDelegate, UICollectionViewDataSource>
@property (nonatomic, strong) CommonTabBar *commonTabBar;
@property (nonatomic, strong) NSArray<CountryModel *> *countries; // 国家列表
@property (nonatomic, strong) UIViewController *currentChildVC; // 当前显示的子控制器
@property (nonatomic, strong) UICollectionView *countryTabBar; // 国家选择标签栏
@property (nonatomic, strong) UIView *contentContainer; // 子控制器容器
@property (nonatomic, assign) NSInteger selectedIndex; // 当前选中的国家索引
// 顶部
@property (nonatomic, strong) UIImageView *logoImage; // logo
@property (nonatomic, strong) UITextField *searchField; // 搜索框
@property (nonatomic, strong) UIImageView *flagIcon; // 国旗
@end
@implementation QuotationViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self initCountries];
[self setupSubviews];
[self setupConstraints];
// 默认选中第一个
self.selectedIndex = 0;
[self switchToCountryAtIndex:self.selectedIndex];
}
#pragma mark - 初始化国家数据
- (void)initCountries {
self.countries = @[
[CountryModel modelWithCode:@"MY"
name:@"马来西亚"
vcClassName:NSStringFromClass([MLXYViewController class])],
[CountryModel modelWithCode:@"CN"
name:@"中国"
vcClassName:NSStringFromClass([CNViewController class])]
];
}
#pragma mark - 创建子视图
- (void)setupSubviews {
self.logoImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo"]];
self.logoImage.contentMode = UIViewContentModeScaleAspectFit;
self.logoImage.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.logoImage];
self.searchField = [[UITextField alloc] init];
self.searchField.placeholder = @"股票名称/代码";
NSAttributedString *placeholder = [[NSAttributedString alloc] initWithString:@"股票名称/代码" attributes:@{
NSForegroundColorAttributeName: [UIColor whiteColor]
}];
self.searchField.attributedPlaceholder = placeholder;
self.searchField.textColor = [UIColor whiteColor];
self.searchField.backgroundColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1];
self.searchField.layer.cornerRadius = 15;
self.searchField.leftView = [[UIImageView alloc] initWithImage:[UIImage systemImageNamed:@"magnifyingglass"]];
self.searchField.leftViewMode = UITextFieldViewModeAlways;
self.searchField.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.searchField];
self.flagIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"logo"]];
self.flagIcon.contentMode = UIViewContentModeScaleAspectFit;
self.flagIcon.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.flagIcon];
UICollectionViewFlowLayout *tabLayout = [[UICollectionViewFlowLayout alloc] init];
tabLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;// 横向滚动
tabLayout.itemSize = CGSizeMake(100, 40); // 每个标签宽100,高40
tabLayout.minimumInteritemSpacing = 0;
self.countryTabBar = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:tabLayout];
self.countryTabBar.backgroundColor = [UIColor blackColor];
self.countryTabBar.delegate = self;
self.countryTabBar.dataSource = self;
[self.countryTabBar registerClass:[UICollectionViewCell class]// 单元格复用类
forCellWithReuseIdentifier:@"CountryTabCell"];
self.countryTabBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.countryTabBar];
// 5. 内容容器,这个承接子视图
self.contentContainer = [[UIView alloc] init];
self.contentContainer.backgroundColor = [UIColor blackColor];
self.contentContainer.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.contentContainer];
NSArray *tabItems = @[
@{@"title":@"首页", @"icon":@"house.fill", @"selected":@NO},
@{@"title":@"行情", @"icon":@"chart.line.uptrend.xyaxis", @"selected":@YES},
@{@"title":@"自选", @"icon":@"plus", @"selected":@NO},
@{@"title":@"我的", @"icon":@"person", @"selected":@NO}
];
self.commonTabBar = [[CommonTabBar alloc] initWithTabItems:tabItems];
self.commonTabBar.delegate = self;
self.commonTabBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.commonTabBar];
}
#pragma mark - 布局约束
- (void)setupConstraints {
// Logo
[NSLayoutConstraint activateConstraints:@[
[self.logoImage.centerYAnchor constraintEqualToAnchor:self.searchField.centerYAnchor],
[self.logoImage.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:15],
[self.logoImage.widthAnchor constraintEqualToConstant:40],
[self.logoImage.heightAnchor constraintEqualToConstant:40]
]];
// 搜索框
[NSLayoutConstraint activateConstraints:@[
[self.searchField.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:50],
[self.searchField.leadingAnchor constraintEqualToAnchor:self.logoImage.trailingAnchor constant:10],
[self.searchField.trailingAnchor constraintEqualToAnchor:self.flagIcon.leadingAnchor constant:-10],
[self.searchField.heightAnchor constraintEqualToConstant:30]
]];
// 国旗
[NSLayoutConstraint activateConstraints:@[
[self.flagIcon.centerYAnchor constraintEqualToAnchor:self.searchField.centerYAnchor],
[self.flagIcon.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-15],
[self.flagIcon.widthAnchor constraintEqualToConstant:40],
[self.flagIcon.heightAnchor constraintEqualToConstant:40]
]];
// 国家
[NSLayoutConstraint activateConstraints:@[
[self.countryTabBar.topAnchor constraintEqualToAnchor:self.searchField.bottomAnchor constant:15],
[self.countryTabBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.countryTabBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.countryTabBar.heightAnchor constraintEqualToConstant:40]
]];
// 子视图容器
[NSLayoutConstraint activateConstraints:@[
[self.contentContainer.topAnchor constraintEqualToAnchor:self.countryTabBar.bottomAnchor],
[self.contentContainer.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.contentContainer.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.contentContainer.bottomAnchor constraintEqualToAnchor:self.commonTabBar.topAnchor]
]];
// 底部TabBar
[NSLayoutConstraint activateConstraints:@[
[self.commonTabBar.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor],
[self.commonTabBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.commonTabBar.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor]
]];
}
#pragma mark - 切换子控制器
- (void)switchToCountryAtIndex:(NSInteger)index {
// 先移除
if (self.currentChildVC) {
[self.currentChildVC willMoveToParentViewController:nil];
[self.currentChildVC.view removeFromSuperview];
[self.currentChildVC removeFromParentViewController];
self.currentChildVC = nil;
}
// 创建新的
CountryModel *selectedCountry = self.countries[index];
Class childVCClass = NSClassFromString(selectedCountry.vcClassName);// 字符串转Class????
UIViewController *childVC = [[childVCClass alloc] init];
// 添加
[self addChildViewController:childVC];
childVC.view.frame = self.contentContainer.bounds;// 适配容器
childVC.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;// 自适应容器大小
[self.contentContainer addSubview:childVC.view];
[childVC didMoveToParentViewController:self];
self.currentChildVC = childVC;
}
#pragma mark - 国家数据源
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.countries.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CountryTabCell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor blackColor];
// 国家名称
UILabel *nameLabel = [cell viewWithTag:100];
if (!nameLabel) {
nameLabel = [[UILabel alloc] init];
nameLabel.tag = 100;
nameLabel.textColor = [UIColor whiteColor];
nameLabel.font = [UIFont systemFontOfSize:15];
nameLabel.textAlignment = NSTextAlignmentCenter;
[cell.contentView addSubview:nameLabel];
nameLabel.frame = cell.contentView.bounds;// 撑满单元格
}
nameLabel.text = self.countries[indexPath.item].name;
// 选中下划线
UIView *selectedLine = [cell viewWithTag:101];
if (!selectedLine) {
selectedLine = [[UIView alloc] init];
selectedLine.tag = 101;
selectedLine.backgroundColor = [UIColor blueColor];
[cell.contentView addSubview:selectedLine];
selectedLine.frame = CGRectMake(30, cell.contentView.bounds.size.height - 7, 40, 4);
}
selectedLine.hidden = !(indexPath.item == self.selectedIndex);
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndex = indexPath.item;
[self.countryTabBar reloadData]; // 刷新标签选中状态
[self switchToCountryAtIndex:indexPath.item]; // 切换到对应国家页面
}
#pragma mark - 底部跳转方法
- (void)tabBarDidSelectIndex:(NSInteger)index {
switch (index) {
case 0:
[self pushHome];
break;
case 1:
break;
case 2:
break;
case 3:
[self pushMine];
break;
}
}
- (void) pushMine {
MyViewController *myViewController = [[MyViewController alloc] init];
[self.navigationController pushViewController:myViewController animated:YES];
}
- (void) pushHome {
HomeViewController *myViewController = [[HomeViewController alloc] init];
[self.navigationController pushViewController:myViewController animated:YES];
}
@end

22
HC/SceneDelegate.m

@ -7,6 +7,8 @@
#import "SceneDelegate.h"
#import "AppDelegate.h"
#import "ViewController.h"
#import "ChartViewController.h"
@interface SceneDelegate ()
@ -16,9 +18,23 @@
- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
UIWindowScene *windowScene = (UIWindowScene *)scene;
if (!windowScene) return;
self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
// 改用窗口场景的屏幕尺寸(兼容 iOS 26+
self.window.frame = windowScene.screen.bounds;
self.window.backgroundColor = [UIColor blackColor];
//ViewController *loginVC = [[ViewController alloc] init];
//UINavigationController *navVC = [[UINavigationController alloc] initWithRootViewController:loginVC];
//self.window.rootViewController = navVC;
// 实例化 ChartViewController
ChartViewController *chartVC = [[ChartViewController alloc] init];
// **设置 ChartViewController 为根视图控制器**
self.window.rootViewController = chartVC;
[self.window makeKeyAndVisible];
}

36
HC/StockKLineModel.h

@ -0,0 +1,36 @@
//
// StockKLineModel.h
// HomilyChartFake
//
// Created by on 2025/11/28.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface StockKLineModel : NSObject
@property (nonatomic, copy) NSString *date; // "2025-11-27"
@property (nonatomic, assign) CGFloat open; //
@property (nonatomic, assign) CGFloat close;//
@property (nonatomic, assign) CGFloat high; //
@property (nonatomic, assign) CGFloat low; //
@property (nonatomic, assign) CGFloat volume; //
// MA均线
@property (nonatomic, assign) CGFloat ma5;
@property (nonatomic, assign) CGFloat ma10;
@property (nonatomic, assign) CGFloat ma20;
// 线
- (BOOL)isUp;
@end
NS_ASSUME_NONNULL_END

21
HC/StockKLineModel.m

@ -0,0 +1,21 @@
//
// StockKLineModel.m
// HomilyChartFake
//
// Created by 洪锡林 on 2025/11/28.
//
#import "StockKLineModel.h"
@implementation StockKLineModel
- (BOOL)isUp {
//A股,收盘 >= 开盘 认为是阳线(红色),这里包含平盘情况
return self.close >= self.open;
}
@end

3
HC/ViewController.h

@ -7,8 +7,7 @@
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@interface ViewController : UIViewController<UITextFieldDelegate>
@end

279
HC/ViewController.m

@ -6,17 +6,294 @@
//
#import "ViewController.h"
#import "HomeViewController.h"
@interface ViewController ()
@property (nonatomic, strong) UIImageView *logoImage;
@property (nonatomic, strong) UILabel *headLabel;// 账号密码登录
@property (nonatomic, strong) UILabel *idLabel;// Homily ID
@property (nonatomic, strong) UILabel *pwdLabel;// 密码
@property (nonatomic, strong) UITextField *account;// 输入框
@property (nonatomic, strong) UITextField *pwd;
@property (nonatomic, strong) UIButton *loginButton;// 登录
@property (nonatomic, strong) UIButton *agreementButton;// 协议
@property (nonatomic, strong) UILabel *agreementLabel;// 协议文字
@property (nonatomic, strong) UILabel *loseLabel;// 忘记密码?
@property (nonatomic, strong) UILabel *questionLabel;// 登录遇到问题?
@property (nonatomic, strong) UIButton *emailButton;// 邮箱登录
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor blackColor];
self.view.userInteractionEnabled = YES;// 开启视图交互
[self setupSubviews];
[self setupConstraints];
NSLog(@"看看导航控制器:%@", self.navigationController ? @"有" : @"哪去了");
}
#pragma mark - 控件
-(void) setupSubviews{
_headLabel = [[UILabel alloc] init];
_headLabel.text = @"账号密码登录";
_headLabel.textColor = [UIColor whiteColor];
_headLabel.font = [UIFont systemFontOfSize:20];
_headLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_headLabel];
// 账号
_idLabel = [[UILabel alloc] init];
_idLabel.text = @"Homily ID | ";
_idLabel.textColor = [UIColor whiteColor];
_idLabel.font = [UIFont systemFontOfSize:16];
_idLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_idLabel];
// 密码
_pwdLabel = [[UILabel alloc] init];
_pwdLabel.text = @"密码 | ";
_pwdLabel.textColor = [UIColor whiteColor];
_pwdLabel.font = [UIFont systemFontOfSize:16];
_pwdLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_pwdLabel];
// 账号输入
_account = [[UITextField alloc] init];
NSDictionary *placeholder = @{
NSForegroundColorAttributeName: [UIColor whiteColor],
NSFontAttributeName: _account.font
};
_account.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@" 请输入帐号" attributes:placeholder];
_account.textColor = [UIColor whiteColor];
_account.layer.borderWidth = 0;
_account.layer.cornerRadius = 5;
_account.delegate = self;
_account.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_account];
// 密码输入
_pwd = [[UITextField alloc] init];
NSDictionary *placeholderAttrs1 = @{
NSForegroundColorAttributeName: [UIColor whiteColor],
NSFontAttributeName: _pwd.font
};
_pwd.attributedPlaceholder = [[NSAttributedString alloc] initWithString:@" 请输入密码" attributes:placeholderAttrs1];
_pwd.secureTextEntry = YES;
_pwd.textColor = [UIColor whiteColor];
_pwd.layer.borderWidth = 0;
_pwd.layer.cornerRadius = 5;
_pwd.delegate = self;
_pwd.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_pwd];
// 登录
_loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_loginButton setTitle:@"登录" forState:UIControlStateNormal];
[_loginButton setTitle:@"这是一个高亮" forState:UIControlStateHighlighted];
[_loginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_loginButton setTitleColor:[UIColor yellowColor] forState:UIControlStateHighlighted];
_loginButton.backgroundColor = [UIColor blueColor];
_loginButton.layer.cornerRadius = 25;// 圆角是高度一半就是圆形按钮
_loginButton.translatesAutoresizingMaskIntoConstraints = NO;
[_loginButton addTarget:self
action:@selector(handleLogin)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_loginButton];
// 协议勾选
_agreementButton = [UIButton buttonWithType:UIButtonTypeCustom];
_agreementButton.layer.borderColor = [UIColor whiteColor].CGColor;
_agreementButton.layer.borderWidth = 1;
_agreementButton.layer.cornerRadius = 3;
_agreementButton.translatesAutoresizingMaskIntoConstraints = NO;
[_agreementButton addTarget:self
action:@selector(agreementButtonSelect:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_agreementButton];
// 协议
_agreementLabel = [[UILabel alloc] init];
_agreementLabel.text = @"我已阅读且同意《注册协议》和《隐私政策》";
_agreementLabel.textColor = [UIColor whiteColor];
_agreementLabel.font = [UIFont systemFontOfSize:12];
_agreementLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_agreementLabel];
// 忘记密码?
_loseLabel = [[UILabel alloc] init];
_loseLabel.text = @"忘记密码?";
_loseLabel.textColor = [UIColor blueColor];
_loseLabel.font = [UIFont systemFontOfSize:14];
_loseLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_loseLabel];
// 登录遇到问题?
_questionLabel = [[UILabel alloc] init];
_questionLabel.text = @"登录遇到问题?";
_questionLabel.textColor = [UIColor whiteColor];
_questionLabel.font = [UIFont systemFontOfSize:14];
_questionLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:_questionLabel];
// 邮箱登录
_emailButton = [UIButton buttonWithConfiguration:[self createEmailButtonConfig] primaryAction:nil];
_emailButton.translatesAutoresizingMaskIntoConstraints = NO;// 禁用自动布局!!!!
[self.view addSubview:_emailButton];
// logo的image
_logoImage = [[UIImageView alloc] init];
_logoImage.image = [UIImage imageNamed:@"logo"];
_logoImage.contentMode = UIViewContentModeScaleAspectFit;
_logoImage.translatesAutoresizingMaskIntoConstraints = NO;// 禁用自动布局!!!!
[self.view addSubview:_logoImage];
[self.view bringSubviewToFront:_account];
[self.view bringSubviewToFront:_pwd];
}
#pragma mark - 协议选中
- (void) agreementButtonSelect:(UIButton *) button {
button.selected = !button.selected;
if (button.selected) {
[button setImage:[UIImage systemImageNamed:@"checkmark"] forState:UIControlStateNormal];
button.tintColor = [UIColor whiteColor];
button.backgroundColor = [UIColor blueColor];
} else {
[button setImage:nil forState:UIControlStateNormal];
button.backgroundColor = [UIColor clearColor];
}
}
#pragma mark - 弹窗提示
// 弹窗
- (void) showAlertWithMessage:(NSString *)message {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
message:message
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
- (void) handleLogin {
// NSString *account = _account.text;
// if (account.length == 0 || ![account isEqualToString:@"90047681"]) {
// [self showAlertWithMessage:@"请输入正确的账号"];
// return;
// }
//
// NSString *pwdText = _pwd.text;
// if (pwdText.length == 0 || ![pwdText isEqualToString:@"123456"]) {
// [self showAlertWithMessage:@"请输入正确的密码"];
// return;
// }
//
// if (!_agreementButton.selected) {
// [self showAlertWithMessage:@"请勾选协议"];
// return;
// }
HomeViewController *homeViewController = [[HomeViewController alloc] init];
[self.navigationController pushViewController:homeViewController animated:YES];
}
#pragma mark - 约束
- (void) setupConstraints {
[NSLayoutConstraint activateConstraints:@[
// logo
[_logoImage.bottomAnchor constraintEqualToAnchor:_headLabel.topAnchor constant:-30],
[_logoImage.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40],
[_logoImage.widthAnchor constraintEqualToConstant:50],
[_logoImage.heightAnchor constraintEqualToConstant:50],
// 标题 顶210,左40,宽200,高20
[_headLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:210],
[_headLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40],
[_headLabel.widthAnchor constraintEqualToConstant:200],
[_headLabel.heightAnchor constraintEqualToConstant:20],
// ID310,左40,宽200,高20
[_idLabel.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:310],
[_idLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40],
[_idLabel.widthAnchor constraintEqualToConstant:200],
[_idLabel.heightAnchor constraintEqualToConstant:20],
// 密码 ID下60,左40,宽200,高20
[_pwdLabel.topAnchor constraintEqualToAnchor:_idLabel.topAnchor constant:60],
[_pwdLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40],
[_account.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-40],
[_pwdLabel.heightAnchor constraintEqualToConstant:20],
// 账号输入框:ID上10,左120,宽200,高40
[_account.topAnchor constraintEqualToAnchor:_idLabel.topAnchor constant:-10],
[_account.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:120],
[_pwd.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-40],
[_account.heightAnchor constraintEqualToConstant:40],
// 密码输入框:密码上10,左120,宽200,高40
[_pwd.topAnchor constraintEqualToAnchor:_pwdLabel.topAnchor constant:-10],
[_pwd.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:120],
[_pwd.widthAnchor constraintEqualToConstant:200],
[_pwd.heightAnchor constraintEqualToConstant:40],
// 登录按钮:密码框下80,左右40,高50
[_loginButton.topAnchor constraintEqualToAnchor:_pwd.bottomAnchor constant:60],
[_loginButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40],
[_loginButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-40],
[_loginButton.heightAnchor constraintEqualToConstant:50],
// 协议按钮:登录下70,左40,宽高20
[_agreementButton.topAnchor constraintEqualToAnchor:_loginButton.bottomAnchor constant:30],
[_agreementButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:40],
[_agreementButton.widthAnchor constraintEqualToConstant:20],
[_agreementButton.heightAnchor constraintEqualToConstant:20],
// 协议:同协议按钮顶,左70,右40
[_agreementLabel.topAnchor constraintEqualToAnchor:_agreementButton.topAnchor],
[_agreementLabel.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:70],
[_agreementLabel.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-40],
[_agreementLabel.heightAnchor constraintEqualToConstant:20],
// 忘记密码:协议按钮下65,水平居中,高20
[_loseLabel.topAnchor constraintEqualToAnchor:_agreementButton.bottomAnchor constant:65],
[_loseLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[_loseLabel.heightAnchor constraintEqualToConstant:20],
// 登录问题:忘记密码下45,水平居中,高20
[_questionLabel.topAnchor constraintEqualToAnchor:_loseLabel.bottomAnchor constant:15],
[_questionLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[_questionLabel.heightAnchor constraintEqualToConstant:20],
// 邮箱登录
[_emailButton.topAnchor constraintEqualToAnchor:_loseLabel.bottomAnchor constant:55],
[_emailButton.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor],
[_emailButton.widthAnchor constraintEqualToConstant:100],
[_emailButton.heightAnchor constraintEqualToConstant:100],
]];
}
// 单写一个
- (UIButtonConfiguration *) createEmailButtonConfig {
UIButtonConfiguration *config = [UIButtonConfiguration plainButtonConfiguration];
config.title = @"邮箱登录";
config.image = [UIImage imageNamed:@"email"];
config.imagePlacement = NSDirectionalRectEdgeTop;// 这里也不对????
config.imagePadding = 8;
return config;
}
#pragma mark - UITextFieldDelegate
- (BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];// 点击return键收起键盘
return YES;
}
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];// 点空白也收起键盘
}
@end
Loading…
Cancel
Save