Commit db23c5fb authored by Wei Han's avatar Wei Han

native UI update

parent 579f896f
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
......
// DetailsViewController.mm
#import "DetailsViewController.h"
@interface AddIssueDetailsViewController ()
@property (nonatomic, strong) UIView *headerView;
@property (nonatomic, strong) UIScrollView *scrollView;
@property (nonatomic, strong) UITextField *locationField;
@property (nonatomic, strong) UITextView *commentField;
@property (nonatomic, strong) UIButton *submitButton;
@property (nonatomic, strong) UIButton *resetButton;
@end
@implementation AddIssueDetailsViewController
......@@ -13,34 +14,125 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
[self setupHeader];
[self setupForm];
// Create all views (don’t position them yet)
[self createHeader];
[self createForm];
}
- (void)setupHeader {
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat topInset = self.view.safeAreaInsets.top;
UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, topInset, self.view.bounds.size.width, 48)];
header.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
header.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.view addSubview:header];
CGFloat headerHeight = 48.0;
// Header layout
self.headerView.frame = CGRectMake(0, topInset, self.view.bounds.size.width, headerHeight);
// Title Label
UILabel *title = [self.headerView viewWithTag:101];
if (title) {
title.frame = CGRectMake(0, 8, self.headerView.bounds.size.width, 32);
}
// Scroll view layout (below header)
CGFloat scrollY = topInset + headerHeight;
self.scrollView.frame = CGRectMake(0, scrollY,
self.view.bounds.size.width,
self.view.bounds.size.height - scrollY);
// Adjust internal subviews (since width may have changed)
self.locationField.frame = CGRectMake(20, 50, self.view.bounds.size.width - 40, 40);
self.commentField.frame = CGRectMake(20, 140, self.view.bounds.size.width - 40, 100);
self.submitButton.frame = CGRectMake(20, 260, self.view.bounds.size.width - 40, 48);
}
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 8, header.bounds.size.width, 32)];
#pragma mark - Setup
- (void)createHeader {
// Header container
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
// Back button (SF Symbol)
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeSystem];
backButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *backImage = [UIImage systemImageNamed:@"chevron.left"];
backImage = [backImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[backButton setImage:backImage forState:UIControlStateNormal];
backButton.tintColor = [UIColor whiteColor];
backButton.backgroundColor = [UIColor clearColor];
[backButton addTarget:self action:@selector(dismissSelf)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:backButton];
// Title label
UILabel *title = [[UILabel alloc] init];
title.translatesAutoresizingMaskIntoConstraints = NO;
title.text = @"Add Issue Details";
title.textColor = UIColor.whiteColor;
title.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
title.textAlignment = NSTextAlignmentCenter;
[header addSubview:title];
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(12, 8, 32, 32);
[backButton setImage:[UIImage imageNamed:@"back24"] forState:UIControlStateNormal];
[backButton addTarget:self action:@selector(dismissSelf) forControlEvents:UIControlEventTouchUpInside];
[header addSubview:backButton];
[self.headerView addSubview:title];
// ✅ Reset button (refresh icon)
self.resetButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.resetButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *refreshImage = [UIImage systemImageNamed:@"arrow.clockwise"];
refreshImage = [refreshImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.resetButton setImage:refreshImage forState:UIControlStateNormal];
self.resetButton.tintColor = [UIColor whiteColor];
self.resetButton.backgroundColor = [UIColor clearColor];
[self.resetButton addTarget:self
action:@selector(handleReset)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.resetButton];
// Status bar background (same color as header)
UIView *statusBarBackground = [[UIView alloc] init];
statusBarBackground.backgroundColor = self.headerView.backgroundColor;
statusBarBackground.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:statusBarBackground];
// Auto Layout
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
// Header
[self.headerView.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:48],
// Back button
[backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:8],
[backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[backButton.widthAnchor constraintEqualToConstant:44],
[backButton.heightAnchor constraintEqualToConstant:44],
// Title centered
[title.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[title.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
// ✅ Reset button (right)
[self.resetButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8],
[self.resetButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.resetButton.widthAnchor constraintEqualToConstant:44],
[self.resetButton.heightAnchor constraintEqualToConstant:44],
// Status bar color fill
[statusBarBackground.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[statusBarBackground.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[statusBarBackground.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[statusBarBackground.bottomAnchor constraintEqualToAnchor:safe.topAnchor],
]];
}
- (void)setupForm {
CGFloat topInset = self.view.safeAreaInsets.top + 48;
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, topInset, self.view.bounds.size.width, self.view.bounds.size.height - topInset)];
- (void)createForm {
self.scrollView = [[UIScrollView alloc] init];
[self.view addSubview:self.scrollView];
UILabel *locationLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 200, 20)];
......@@ -48,7 +140,7 @@
locationLabel.font = [UIFont boldSystemFontOfSize:16];
[self.scrollView addSubview:locationLabel];
self.locationField = [[UITextField alloc] initWithFrame:CGRectMake(20, 50, self.view.bounds.size.width - 40, 40)];
self.locationField = [[UITextField alloc] initWithFrame:CGRectZero];
self.locationField.borderStyle = UITextBorderStyleRoundedRect;
[self.scrollView addSubview:self.locationField];
......@@ -57,14 +149,14 @@
commentLabel.font = [UIFont boldSystemFontOfSize:16];
[self.scrollView addSubview:commentLabel];
self.commentField = [[UITextView alloc] initWithFrame:CGRectMake(20, 140, self.view.bounds.size.width - 40, 100)];
self.commentField = [[UITextView alloc] initWithFrame:CGRectZero];
self.commentField.layer.borderColor = [UIColor lightGrayColor].CGColor;
self.commentField.layer.borderWidth = 1.0;
self.commentField.layer.cornerRadius = 8;
[self.scrollView addSubview:self.commentField];
self.submitButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.submitButton.frame = CGRectMake(20, 260, self.view.bounds.size.width - 40, 48);
self.submitButton.frame = CGRectZero;
self.submitButton.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
[self.submitButton setTitle:@"Submit" forState:UIControlStateNormal];
[self.submitButton setTitleColor:UIColor.whiteColor forState:UIControlStateNormal];
......@@ -73,6 +165,23 @@
[self.scrollView addSubview:self.submitButton];
}
- (void)handleReset {
NSLog(@"🔄 Reset button tapped");
self.locationField.text = @"";
self.commentField.text = @"";
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Fields Cleared"
message:@"All inputs have been reset."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:nil]];
[self presentViewController:alert animated:YES completion:nil];
}
#pragma mark - Actions
- (void)dismissSelf {
[self dismissViewControllerAnimated:YES completion:nil];
}
......@@ -86,4 +195,3 @@
}
@end
......@@ -29,55 +29,104 @@
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// Get safe area + bounds
CGFloat topInset = self.view.safeAreaInsets.top;
CGFloat headerHeight = 48.0;
// Layout header
self.headerView.frame = CGRectMake(0, topInset, self.view.bounds.size.width, headerHeight);
// Layout title
self.titleLabel.frame = CGRectMake(0, 8, self.headerView.bounds.size.width, 32);
self.helpButton.frame = CGRectMake(self.headerView.bounds.size.width - 44, 8, 32, 32);
// Layout items within header
self.backButton.frame = CGRectMake(12, 8, 32, 32);
self.helpButton.frame = CGRectMake(self.headerView.bounds.size.width - 44, 8, 32, 32);
self.titleLabel.frame = CGRectMake(0, 8, self.headerView.bounds.size.width, 32);
// Layout scroll view
CGFloat scrollY = topInset + headerHeight;
self.scrollView.frame = CGRectMake(0, scrollY, self.view.bounds.size.width,
self.view.bounds.size.height - scrollY);
self.scrollView.frame = CGRectMake(0, scrollY, self.view.bounds.size.width, self.view.bounds.size.height - scrollY);
self.planImageView.frame = self.scrollView.bounds;
// Make absolutely sure header is above scroll view
[self.view bringSubviewToFront:self.headerView];
}
#pragma mark - UI Creation
- (void)createHeader {
// 🟩 Status bar background view
UIView *statusBarBackground = [[UIView alloc] init];
statusBarBackground.backgroundColor = [UIColor colorWithRed:0/255.0
green:109/255.0
blue:141/255.0
alpha:1];
statusBarBackground.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:statusBarBackground];
// 🟦 Header background view
self.headerView = [[UIView alloc] init];
self.headerView.backgroundColor = [UIColor colorWithRed:0/255.0 green:109/255.0 blue:141/255.0 alpha:1];
self.headerView.backgroundColor = statusBarBackground.backgroundColor;
self.headerView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.headerView];
// Back button
self.backButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.backButton setImage:[UIImage imageNamed:@"back24"] forState:UIControlStateNormal];
[self.backButton addTarget:self action:@selector(handleBack) forControlEvents:UIControlEventTouchUpInside];
self.backButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.backButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *backImage = [[UIImage systemImageNamed:@"chevron.left"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.backButton setImage:backImage forState:UIControlStateNormal];
self.backButton.tintColor = [UIColor whiteColor];
[self.backButton addTarget:self action:@selector(handleBack)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.backButton];
// Title
// Title label
self.titleLabel = [[UILabel alloc] init];
self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
self.titleLabel.text = @"Plan Viewer";
self.titleLabel.textColor = UIColor.whiteColor;
self.titleLabel.font = [UIFont systemFontOfSize:18 weight:UIFontWeightMedium];
self.titleLabel.textAlignment = NSTextAlignmentCenter;
[self.headerView addSubview:self.titleLabel];
// Help button
self.helpButton = [UIButton buttonWithType:UIButtonTypeCustom];
[self.helpButton setImage:[UIImage imageNamed:@"btn_white_help_3x"] forState:UIControlStateNormal];
[self.helpButton addTarget:self action:@selector(showTutorial) forControlEvents:UIControlEventTouchUpInside];
self.helpButton = [UIButton buttonWithType:UIButtonTypeSystem];
self.helpButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *helpImage = [[UIImage systemImageNamed:@"questionmark.circle"]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[self.helpButton setImage:helpImage forState:UIControlStateNormal];
self.helpButton.tintColor = [UIColor whiteColor];
[self.helpButton addTarget:self action:@selector(showTutorial)
forControlEvents:UIControlEventTouchUpInside];
[self.headerView addSubview:self.helpButton];
// ✅ Constraints
UILayoutGuide *safe = self.view.safeAreaLayoutGuide;
[NSLayoutConstraint activateConstraints:@[
// Status bar background
[statusBarBackground.topAnchor constraintEqualToAnchor:self.view.topAnchor],
[statusBarBackground.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[statusBarBackground.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[statusBarBackground.bottomAnchor constraintEqualToAnchor:safe.topAnchor],
// Header pinned below safe area
[self.headerView.topAnchor constraintEqualToAnchor:safe.topAnchor],
[self.headerView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
[self.headerView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
[self.headerView.heightAnchor constraintEqualToConstant:48],
// Back button
[self.backButton.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor constant:8],
[self.backButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.backButton.widthAnchor constraintEqualToConstant:44],
[self.backButton.heightAnchor constraintEqualToConstant:44],
// Help button
[self.helpButton.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor constant:-8],
[self.helpButton.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
[self.helpButton.widthAnchor constraintEqualToConstant:44],
[self.helpButton.heightAnchor constraintEqualToConstant:44],
// Title centered
[self.titleLabel.centerXAnchor constraintEqualToAnchor:self.headerView.centerXAnchor],
[self.titleLabel.centerYAnchor constraintEqualToAnchor:self.headerView.centerYAnchor],
]];
}
- (void)createScrollView {
......@@ -94,7 +143,7 @@
UIImage *testImage = [UIImage imageNamed:@"image_placeholder"];
if (!testImage) {
NSLog(@"❌ image_placeholder not found in bundle!");
self.planImageView.backgroundColor = [UIColor systemTealColor];
self.planImageView.backgroundColor = [UIColor whiteColor];
// 👉 Temporary test button
UIButton *testButton = [UIButton buttonWithType:UIButtonTypeSystem];
......@@ -148,4 +197,9 @@
return self.planImageView;
}
#pragma mark - Status Bar Style
- (UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent; // ✅ White text/icons
}
@end
......@@ -7,16 +7,34 @@
DashboardHeaderView *_headerView;
UIScrollView *_scrollView;
UIView *_contentContainer;
NSMutableDictionary *_sectionViews;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0]; // #F2F2F2
self.view.backgroundColor = [UIColor colorWithWhite:0.96 alpha:1.0];
_sectionViews = [NSMutableDictionary dictionary];
[self setupHeader];
[self setupScrollContent];
[self setupFooter];
[self fetchDashboardData];
}
#pragma mark - Layout
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
UIView *footerView = self.view.subviews.lastObject;
CGFloat footerHeight = 80.0;
CGFloat bottomInset = self.view.safeAreaInsets.bottom;
footerView.frame = CGRectMake(
0,
self.view.bounds.size.height - footerHeight - bottomInset,
self.view.bounds.size.width,
footerHeight + bottomInset
);
}
#pragma mark - Header
......@@ -29,73 +47,47 @@
backgroundImage:[UIImage imageNamed:@"header_bg"]
overlayImage:[UIImage imageNamed:@"overlay"]];
[self.view addSubview:_headerView];
// Create Back Button
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeSystem];
backButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *backImage = [UIImage systemImageNamed:@"chevron.left"];
backImage = [backImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *backImage = [[UIImage systemImageNamed:@"chevron.left"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[backButton setImage:backImage forState:UIControlStateNormal];
backButton.tintColor = [UIColor whiteColor];
backButton.layer.cornerRadius = 18;
backButton.backgroundColor = [UIColor clearColor];
backButton.clipsToBounds = YES;
[backButton addTarget:self
action:@selector(handleBackButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[backButton addTarget:self action:@selector(handleBackButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:backButton];
// Create Menu Button
UIButton *menuButton = [UIButton buttonWithType:UIButtonTypeSystem];
menuButton.translatesAutoresizingMaskIntoConstraints = NO;
UIImage *menuImage = [UIImage systemImageNamed:@"line.3.horizontal"];
menuImage = [menuImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *menuImage = [[UIImage systemImageNamed:@"line.3.horizontal"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[menuButton setImage:menuImage forState:UIControlStateNormal];
menuButton.tintColor = [UIColor whiteColor];
menuButton.backgroundColor = [UIColor clearColor];
menuButton.contentEdgeInsets = UIEdgeInsetsMake(8, 8, 8, 8);
[menuButton addTarget:self
action:@selector(handleMenuButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
[menuButton addTarget:self action:@selector(handleMenuButtonTapped) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:menuButton];
// ✅ Use Auto Layout constraints to respect safe area
[NSLayoutConstraint activateConstraints:@[
// Back button - top left
[backButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:8],
[backButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4],
[backButton.widthAnchor constraintEqualToConstant:44],
[backButton.heightAnchor constraintEqualToConstant:44],
// Menu button - top right
[menuButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-8],
[menuButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4],
[menuButton.widthAnchor constraintEqualToConstant:44],
[menuButton.heightAnchor constraintEqualToConstant:44],
]];
[backButton.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor constant:8],
[backButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4],
[backButton.widthAnchor constraintEqualToConstant:44],
[backButton.heightAnchor constraintEqualToConstant:44],
[menuButton.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-8],
[menuButton.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor constant:4],
[menuButton.widthAnchor constraintEqualToConstant:44],
[menuButton.heightAnchor constraintEqualToConstant:44],
]];
}
- (void)handleBackButtonTapped {
NSLog(@"🔙 Back button tapped – attempting to close DashboardViewController");
NSLog(@"🔙 Back button tapped");
if (self.presentingViewController) {
[self dismissViewControllerAnimated:YES completion:nil];
} else if (self.navigationController) {
[self.navigationController popViewControllerAnimated:YES];
} else {
NSLog(@"⚠️ No parent VC found to close!");
}
}
- (void)handleMenuButtonTapped {
NSLog(@"🍔 Menu button tapped – (TODO: open side menu or modal)");
NSLog(@"🍔 Menu button tapped");
}
#pragma mark - Footer
......@@ -116,145 +108,139 @@
footerView.layer.shadowOffset = CGSizeMake(0, -1);
[self.view addSubview:footerView];
// Button info
NSArray *titles = @[ @"Make Appointment", @"Add Issue", @"View Access Item" ];
NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ];
CGFloat visibleButtonHeight = footerHeight;
NSArray *icons = @[ @"calendar", @"plus.circle", @"list.bullet" ];
CGFloat buttonWidth = self.view.bounds.size.width / titles.count;
for (NSInteger i = 0; i < titles.count; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, visibleButtonHeight);
button.frame = CGRectMake(i * buttonWidth, 0, buttonWidth, footerHeight);
[button setTitle:titles[i] forState:UIControlStateNormal];
[button setTitleColor:[UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0]
forState:UIControlStateNormal];
[button setTitleColor:[UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0] forState:UIControlStateNormal];
button.titleLabel.font = [UIFont boldSystemFontOfSize:13];
button.tintColor = [UIColor colorWithRed:0.0 green:0.43 blue:0.55 alpha:1.0];
[button setImage:[UIImage systemImageNamed:icons[i]] forState:UIControlStateNormal];
UIImage *icon = [UIImage systemImageNamed:icons[i]];
[button setImage:icon forState:UIControlStateNormal];
// Center icon above title
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
// Adjust spacing between image and text
CGFloat spacing = 6.0;
CGSize imageSize = button.imageView.frame.size;
CGSize titleSize = button.titleLabel.frame.size;
button.titleEdgeInsets = UIEdgeInsetsMake(
imageSize.height + spacing, // move text below image
-imageSize.width, // center horizontally
0,
0
);
button.imageEdgeInsets = UIEdgeInsetsMake(
-titleSize.height - spacing / 2, // move image up
0,
0,
-titleSize.width
);
button.titleEdgeInsets = UIEdgeInsetsMake(imageSize.height + spacing, -imageSize.width, 0, 0);
button.imageEdgeInsets = UIEdgeInsetsMake(-titleSize.height - spacing / 2, 0, 0, -titleSize.width);
button.tag = i;
[button addTarget:self action:@selector(footerButtonTapped:)
forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:@selector(footerButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:button];
// Divider line between buttons (except after last one)
if (i < titles.count - 1) {
UIView *divider = [[UIView alloc] initWithFrame:CGRectMake(
(i + 1) * buttonWidth - 0.5,
10,
1,
footerHeight - 20
)];
UIView *divider = [[UIView alloc] initWithFrame:CGRectMake((i + 1) * buttonWidth - 0.5, 10, 1, footerHeight - 20)];
divider.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
divider.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
[footerView addSubview:divider];
}
}
}
- (void)footerButtonTapped:(UIButton *)sender {
NSLog(@"🟢 Footer button tapped with tag: %ld", (long)sender.tag);
NSString *title = sender.titleLabel.text;
NSLog(@"Footer button tapped: %@", title);
switch (sender.tag) {
case 0:
// Make Appointment
NSLog(@"Make Appointment tapped");
break;
case 1: {
// Add Issue
PlanViewController *planVC = [[PlanViewController alloc] init];
planVC.modalPresentationStyle = UIModalPresentationFullScreen;
if (!planVC) {
NSLog(@"❌ PlanViewController class not found!");
return;
}
[self presentViewController:planVC animated:YES completion:nil];
break;
}
case 2:
// View Access Item
NSLog(@"View Access Item tapped");
break;
default:
break;
}
}
#pragma mark - Scrollable Content
#pragma mark - Scroll Content
- (void)setupScrollContent {
CGFloat topOffset = 220.0;
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, topOffset, self.view.bounds.size.width, self.view.bounds.size.height - topOffset)];
_scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_scrollView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_scrollView];
_scrollView.clipsToBounds = NO;
_contentContainer.clipsToBounds = NO;
_contentContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _scrollView.bounds.size.width, 800)];
_contentContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _scrollView.bounds.size.width, 0)];
_contentContainer.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[_scrollView addSubview:_contentContainer];
CGFloat y = 20;
y = [self addSectionWithTitle:@"Project Update" text:@"12/10/2025\nAnnouncement Title" y:y];
y = [self addSectionWithTitle:@"Appointments" text:@"You have a joint inspection on 25 Oct 2025" y:y];
y = [self addSectionWithTitle:@"Issue Updates" text:@"Issue REF123 has been lodged." y:y];
_contentContainer.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, y + 20);
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, CGRectGetMaxY(_contentContainer.frame));
// Add 3 fixed section titles, store them for later population
NSArray *sectionNames = @[ @"Project Update", @"Appointments", @"Issue Updates" ];
for (NSString *name in sectionNames) {
UILabel *header = [[UILabel alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 24)];
header.text = name;
header.font = [UIFont boldSystemFontOfSize:18];
[_contentContainer addSubview:header];
y += 30;
UIView *sectionContainer = [[UIView alloc] initWithFrame:CGRectMake(0, y, self.view.bounds.size.width, 0)];
[_contentContainer addSubview:sectionContainer];
_sectionViews[name] = sectionContainer;
y += 20; // spacing before next section
}
_contentContainer.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, y);
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, y);
}
#pragma mark - Networking
- (void)fetchDashboardData {
NSURL *url = [NSURL URLWithString:@"https://jsonplaceholder.typicode.com/posts?_limit=9"];
__weak typeof(self) weakSelf = self;
[[[NSURLSession sharedSession] dataTaskWithURL:url
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) return;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf populateSectionsWithData:json];
});
}] resume];
}
- (CGFloat)addSectionWithTitle:(NSString *)title text:(NSString *)text y:(CGFloat)y {
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 22)];
titleLabel.text = title;
titleLabel.font = [UIFont boldSystemFontOfSize:18];
[_contentContainer addSubview:titleLabel];
y += 30;
UIView *card = [[UIView alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 100)];
card.backgroundColor = [UIColor whiteColor];
card.layer.cornerRadius = 8;
card.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
card.layer.shadowOpacity = 0.8;
card.layer.shadowOffset = CGSizeMake(0, 1);
[_contentContainer addSubview:card];
UILabel *body = [[UILabel alloc] initWithFrame:CGRectMake(12, 12, card.bounds.size.width - 24, 80)];
body.text = text;
body.numberOfLines = 0;
body.font = [UIFont systemFontOfSize:15];
[card addSubview:body];
return y + 120;
- (void)populateSectionsWithData:(NSArray *)data {
NSArray *sectionKeys = @[ @"Project Update", @"Appointments", @"Issue Updates" ];
int itemsPerSection = (int)ceil(data.count / 3.0);
CGFloat sectionBottomY = 0;
for (int i = 0; i < sectionKeys.count; i++) {
NSString *key = sectionKeys[i];
UIView *sectionContainer = _sectionViews[key];
CGFloat y = 0;
NSArray *subset = [data subarrayWithRange:NSMakeRange(i * itemsPerSection,
MIN(itemsPerSection, data.count - i * itemsPerSection))];
for (NSDictionary *item in subset) {
UIView *card = [[UIView alloc] initWithFrame:CGRectMake(16, y, self.view.bounds.size.width - 32, 100)];
card.backgroundColor = [UIColor whiteColor];
card.layer.cornerRadius = 8;
card.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor;
card.layer.shadowOpacity = 0.8;
card.layer.shadowOffset = CGSizeMake(0, 1);
UILabel *body = [[UILabel alloc] initWithFrame:CGRectMake(12, 12, card.bounds.size.width - 24, 80)];
body.text = item[@"title"];
body.numberOfLines = 2;
body.font = [UIFont systemFontOfSize:15];
[card addSubview:body];
[sectionContainer addSubview:card];
y += 120;
}
sectionContainer.frame = CGRectMake(0, sectionContainer.frame.origin.y, self.view.bounds.size.width, y);
sectionBottomY = CGRectGetMaxY(sectionContainer.frame) + 20;
}
_contentContainer.frame = CGRectMake(0, 0, _scrollView.bounds.size.width, sectionBottomY);
_scrollView.contentSize = CGSizeMake(_scrollView.bounds.size.width, sectionBottomY);
}
@end
......@@ -8,32 +8,32 @@
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<string>ios-arm64_x86_64-simulator</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>QmsPluginFramework.framework/QmsPluginFramework</string>
<key>LibraryIdentifier</key>
<string>ios-arm64_x86_64-simulator</string>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>QmsPluginFramework.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
<string>x86_64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment